Matplotlib:使用figure对象初始化p

2024-04-25 11:37:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为一个特定的实验建立一类绘图工具。 我现在有两个plot方法,一个是使用imshow()的静态plot,另一个是“movie”格式 使用imshow()。

无论是方法还是将来的任何方法,都会获取与我可能编写的任何特定绘图方法相同的参数。在使用plot类时,所有这些参数都在config对象中。

我不想重写所有plot方法中的代码。我想初始化一个对象(我认为是AxesImage),该对象将设置这些参数:vmin、vmax、extent戥im、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)

Tags: ofthe对象方法data参数plotplt
2条回答

要显示绘图,您需要使用fig.canvas.draw(),其中figFigure类的实例。fig.canvas.draw()是交互式shell(读:pylab)函数的API版本draw()

如果需要从AxesImage对象获取AxesFigure,可以分别调用im.get_axes()im.get_figure()

就编写“好的”面向对象代码而言,the user interface examples可能是一个很好的起点。

首先,您需要了解一点matplotlib的体系结构(请参阅here以获取创始人和当前主要开发人员的一篇长文章)。在backend层的底部,处理渲染和与硬件的对话。在这个层的顶部是artists,它知道如何通过告诉backend对象该做什么来绘制它们。在该层的顶部是pyplotstate machine接口,它模拟MATLAB

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

这种设计的一个退步是,Artist的给定实例化可以正好在一个图中(并且在图之间移动它们很困难),因此您不能生成一个AxesImage对象,然后继续重用它。

这种设计还分离了Artists所知道的内容。Axes对象知道诸如记号位置、标签和显示范围之类的内容(它通过了解Axis对象来实现这一点,但这一点正在变得更加复杂)。像vminvmax这样的东西被封装在Normalizedoc)对象中,由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)

您可以将一整套Kwarg包装起来,以方便重复使用:

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

ax2.imshow(..., **my_imshow_args)

咖喱味:

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)

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

plt.imshow = my_imshow

还有一个rcParams接口,它允许您以全局方式更改matplotlib的许多位和片段的默认值。

以及yet another实现这一点的方法(通过partial

相关问题 更多 >