Matplotlib:使用图形对象初始化绘图

wbg*_*wbg 6 python plot matplotlib

我正在为特定的实验构建一类绘图工具.我目前有两种绘图方法,一种是使用imshow()的静态绘图,另一种是使用imshow()的"movie"格式.

这两种方法和任何将来的方法都可以获得与我可能编写的任何特定绘图方法相同的参数.我在使用plot类时在config对象中拥有所有这些参数.

我不想在每个绘图方法中重写代码.我想初始化一个对象(AxesImage,我认为)将设置这些args:vmin,vmax,extent_dim,Xlocs,Xlabels,Ylocs,Ylabels.

然后我将该对象传递给执行其他特定操作的各种方法.我不明白怎么做...

import matplotlib.pyplot as plt

data = data_dict[type] # could be real part of a complex number, phase, or the mag...
v_min, v_max = self.get_data_type_scale(data_dict, Type)
freq = data_dict['freq']

# essentially sets the aspect of the plot since the x and y resolutions could be different   
extent_dim = self._get_extent(2)
# gets the labels for physical dimensions of the experiment
Xlocs,Xlabels,Ylocs,Ylabels = self._get_ticks(5,5,extent_dim)

# in the guts of a plot method, the basic idea is the call below.  

plt.imshow(data[0,:,:],cmap='jet',vmin=v_min,...
vmax=v_max,origin='lower', extent = extent_dim)

plt.title('Type:  %s  Freq: %.3e Hz' %(Type,data_dict['freq'][0]) )
plt.xticks(Xlocs, Xlabels)
plt.yticks(Ylocs,Ylabels)
Run Code Online (Sandbox Code Playgroud)

tac*_*ell 12

您需要首先了解一些架构matplotlib(请参阅此处以获取创始人和当前首席开发人员的长篇文章).在backend图层的底部,处理渲染和与硬件交谈.在该层的顶部是artists知道如何通过告诉backend对象做什么来绘制它们自己.在该层的顶部是模仿的pyplot 状态机接口MATLAB.

您在图中看到的所有内容都在内部表示为Artist,艺术家可以包含其他艺术家.例如,Axes对象跟踪它的子项Artists,即轴刺,标记,标签,线或图像等,Axes对象是对象的子Figure对象.当你告诉一个人物画自己(通过fig.canvas.draw())所有的孩子艺术家是递归绘制.

这个设计的一个缺点是,一个给定的实例Artist可以只是一个图形(并且在图形之间移动它们很难),所以你不能制作一个AxesImage对象然后继续重复使用它.

这个设计也分开Artists了解. Axes对象知道诸如刻度位置和标签之类的事情以及显示范围(通过了解Axis对象来做到这一点,但这会更多地进入杂草).之类的东西vmin,并vmax封装在Normalize(DOC)对象将AxesImage保持跟踪.这意味着您需要分清处理列表中所有内容的方式.

我建议在这里使用类似工厂的图案,或者像咖喱一样的图案

工厂类:

def set_up_axes(some, arguements):
    '''
    Factory to make configured axes (
    '''
    fig, ax = plt.subplots(1, 1) # or what ever layout you want
    ax.set_*(...)
    return fig, ax


my_norm = matplotlib.colors.Normalize(vmin, mmax) # or write a factory to do fancier stuff
fig, ax = set_up_axes(...)
ax.imshow(..., norm=my_norm)
fig2, ax2 = set_up_axes(...)
ax2.imshow(..., norm=mynorm)
Run Code Online (Sandbox Code Playgroud)

您可以将一整套kwargs包装起来,以便轻松地重复使用它们:

my_imshow_args = {'extent':[...],
                  'interpolation':'nearest',
                  'norm': my_norm,
                   ...}

ax2.imshow(..., **my_imshow_args)
Run Code Online (Sandbox Code Playgroud)

咖喱,如:

def my_imshow(im, ax=None, *args, **kwargs):
    if ax is None:
        ax = plt.gca()
    # do all of your axes set up
    ax.set_xlim(..)

    # set default vmin and vmax
    # you can drop some of these conditionals if you don't want to be
    # able to explicitly override the defaults
    if 'norm' not in kwargs:
        vmin = kwargs.pop('vmin', None)
        vmax = kwargs.pop('vmax', None)
        if vmin is None:
            vmin = default_vmin # or what ever
        if vmax is None:
            vmax = default_vmax
        my_norm = matplotlib.colors.Normalize(vmin, mmax)
        kwargs['norm'] = norm

    # add a similar block for `extent` 
    # or any other kwargs you want to change the default of

    ax.figure.canvas.draw() # if you want to force a re-draw
    return ax.imshow(im, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

如果你想变得超级聪明,你可以plt.imshow使用你的版本进行修补

plt.imshow = my_imshow
Run Code Online (Sandbox Code Playgroud)

还有rcParams接口,它允许您以matplotlib全局方式更改许多位的默认值.

另一种方法来实现这一目标(通过partial)