2017-05-01 1 views
4

J'ai remarqué que je peux ajouter mes propres attributs à matplotlib.axes.Axes() et matplotlib.figure.Figure() instances. Par exemple,Ajout d'attributs personnalisés aux occurrences matplotlib Figure et Axes: peu recommandées?

import matplotlib as mpl 
f = mpl.figure.Figure() 
a = f.add_subplot() 
a.foo = 'bar' 

En pratique, je pourrais vous ajouter un à un axe exemple de basemap objet en utilisant quelque chose comme

import mpl_toolkits.basemap as basemap  
a.basemap = basemap.Basemap('mollweide', ax=a) 

Alors que je peux ajouter des fonctionnalités géographiques dans un plus object- orienté, manière intuitive. Est-ce une caractéristique documentée/fiable de ces objets, ou est-ce accidentel? En d'autres termes, puis-je "utiliser" en toute sécurité?

Répondre

2

Selon ce example, vous pouvez ajouter une nouvelle propriété pour la classe de figure personnalisée. Cependant, pour la classe Axes, cette tâche est plus compliquée. Vous devez faire propre classe Haches

from matplotlib.pyplot import figure, show 
from matplotlib.figure import Figure 
from matplotlib.axes import Subplot 
from mpl_toolkits.basemap import Basemap 

# custom Figure class with foo property 
class MyFigure(Figure): 
    def __init__(self, *args, **kwargs): 
     self.foo = kwargs.pop('foo', 'bar') 
     Figure.__init__(self, *args, **kwargs) 

# custom Axes class 
class MyAxes(Subplot): 
    def __init__(self, *args, **kwargs): 
     super(MyAxes, self).__init__(*args, **kwargs) 

    # add my axes 
    @staticmethod 
    def from_ax(ax=None, fig=None, *args, **kwargs): 
     if ax is None: 
      if fig is None: fig = figure(facecolor='w', edgecolor='w') 
      ax = MyAxes(fig, 1, 1, 1, *args, **kwargs) 
      fig.add_axes(ax) 
     return ax 

# test run 
# custom figure 
fig = figure(FigureClass=MyFigure, foo='foo') 
print (type(fig), fig.foo) 

# add to figure custom axes 
ax = MyAxes.from_ax(fig=fig) 
print (type(fig.gca())) 

# create Basemap instance and store it to 'm' property 
ax.m = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64, urcrnrlat=49, 
projection='lcc', lat_1=33, lat_2=45, lon_0=-95, resolution='c') 
ax.m.drawcoastlines(linewidth=.25) 
ax.m.drawcountries(linewidth=.25) 
ax.m.fillcontinents(color='coral', lake_color='aqua') 

print (ax.m) 
show() 

Sortie:

<class '__main__.MyFigure'> foo 
<class '__main__.MyAxes'> 
<mpl_toolkits.basemap.Basemap object at 0x107fc0358> 

enter image description here

Cependant, mon opinion est que vous n'avez pas besoin de faire m propriété de classe axes. Vous devez appeler toutes les fonctions selon le fond de carte dans la classe d'axes personnalisés, c'est-à-dire dans __init___ (ou faire une méthode spéciale comme set_basemap).

+1

Merci, c'était extrêmement utile. J'ai une fonction de formatage automatique utile pour les types de figures que je fais habituellement, et je vais faire de cette définition une méthode d'une sous-classe 'Figure' (beaucoup plus propre). Et vous avez raison, je ne vais probablement pas déranger les axes de sous-classement et je vais faire les conversions de coordonnées manuellement. J'utiliserais 'cartopy' (qui est beaucoup plus orienté objet/intuitif), mais malheureusement' basemap' est encore beaucoup plus riche en fonctionnalités (par exemple, les étiquettes de longitude/latitude dans 'cartopy' sont pratiquement inutilisables) . –