【问题标题】:Adding custom attributes to matplotlib Figure and Axes instances: ill-advised?向 matplotlib Figure 和 Axes 实例添加自定义属性:不明智?
【发布时间】:2017-05-01 03:28:56
【问题描述】:

我注意到我可以将自己的属性添加到 matplotlib.axes.Axes()matplotlib.figure.Figure() 实例。例如,

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

实际上,我可能想使用类似

的方式将 底图实例 添加到坐标区对象
import mpl_toolkits.basemap as basemap    
a.basemap = basemap.Basemap('mollweide', ax=a)

这样我就可以以更面向对象、更直观的方式添加地理特征。这是这些对象的记录/可靠功能,还是偶然的?换句话说,我可以“安全地”使用它吗?

【问题讨论】:

    标签: python python-3.x matplotlib matplotlib-basemap


    【解决方案1】:

    根据example,您可以为自定义 Figure 类添加任何新属性。然而,对于 Axes 类,此类任务更为复杂。你必须制作自己的 Axes 类

    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()
    

    输出:

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

    但是我的意见是,您不需要创建轴类的 m 属性。您必须根据自定义轴类中的底图调用所有函数,即在__init___ 中(或制作像set_basemap 这样的特殊方法)。

    【讨论】:

    • 谢谢,这非常有帮助。对于我通常制作的图形类型,我有一个有用的自动格式化功能,而是将该定义作为Figure 子类的方法(更清晰)。你是对的,我可能不会打扰轴的子类化,只会手动进行坐标转换。我会使用cartopy(它更加面向对象/直观),但不幸的是basemap 仍然是一种方式,功能更丰富(例如,cartopy 中的经度/纬度标签几乎无法使用)。
    猜你喜欢
    • 2016-07-02
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多