Matplotlib返回一个绘图对象

Sim*_*mon 15 python plot matplotlib

我有一个包装的函数,pyplot.plt所以我可以使用经常使用的默认值快速创建图形:

def plot_signal(time, signal, title='', xlab='', ylab='',
                line_width=1, alpha=1, color='k',
                subplots=False, show_grid=True, fig_size=(10, 5)):

    # Skipping a lot of other complexity here

    f, axarr = plt.subplots(figsize=fig_size)
    axarr.plot(time, signal, linewidth=line_width,
               alpha=alpha, color=color)
    axarr.set_xlim(min(time), max(time))
    axarr.set_xlabel(xlab)
    axarr.set_ylabel(ylab)
    axarr.grid(show_grid)

    plt.suptitle(title, size=16)
    plt.show()
Run Code Online (Sandbox Code Playgroud)

但是,有时候我希望能够返回绘图,以便我可以手动添加/编辑特定图形的内容.例如,我希望能够更改轴标签,或者在调用函数后向绘图添加第二行:

import numpy as np

x = np.random.rand(100)
y = np.random.rand(100)

plot = plot_signal(np.arange(len(x)), x)

plot.plt(y, 'r')
plot.show()
Run Code Online (Sandbox Code Playgroud)

我已经看到了几个问题(如何从Pandas绘图函数返回matplotlib.figure.Figure对象?AttributeError:'图'对象没有属性'plot')因此我尝试添加以下内容到功能结束:

  • return axarr

  • return axarr.get_figure()

  • return plt.axes()

但是,它们都返回了类似的错误: AttributeError: 'AxesSubplot' object has no attribute 'plt'

什么是返回绘图对象的正确方法,以便以后编辑?

Imp*_*est 15

我认为错误是不言自明的.没有这样的东西pyplot.plt,或类似的东西.plt是进口时pyplot的准标准缩写形式,即import matplotlib.pyplot as plt.

关于这个问题,第一种方法return axarr是最通用的方法.你得到一个轴或一组轴,并可以绘制它.

代码可能看起来像

def plot_signal(x,y, ..., **kwargs):
    # Skipping a lot of other complexity her
    f, ax = plt.subplots(figsize=fig_size)
    ax.plot(x,y, ...)
    # further stuff
    return ax

ax = plot_signal(x,y, ...)
ax.plot(x2, y2, ...)
plt.show()
Run Code Online (Sandbox Code Playgroud)


小智 9

matplotlib 文档中,推荐使用的签名是:

def my_plotter(ax, data1, data2, param_dict):
    """
    A helper function to make a graph

    Parameters
    ----------
    ax : Axes
        The axes to draw to

    data1 : array
       The x data

    data2 : array
       The y data

    param_dict : dict
       Dictionary of keyword arguments to pass to ax.plot

    Returns
    -------
    out : list
        list of artists added
    """
    out = ax.plot(data1, data2, **param_dict)
    
    return out
Run Code Online (Sandbox Code Playgroud)

这可以用作:

data1, data2, data3, data4 = np.random.randn(4, 100)
fig, ax = plt.subplots(1, 1)
my_plotter(ax, data1, data2, {'marker': 'x'})
Run Code Online (Sandbox Code Playgroud)

您应该传递轴而不是图形。AFigure包含一个或多个Axes. Axes是一个可以以 xy 格式、3d 绘图等指定点的区域。图是我们在其中绘制数据的图形 - 它可以是 jupyter 笔记本或 Windows GUI 等。


小智 8

这实际上是一个很好的问题,我花了很多年才弄明白。一个很好的方法是将图形对象传递给您的代码,并让您的函数添加一个轴,然后返回更新后的图形。下面是一个例子:

fig_size = (10, 5)
f = plt.figure(figsize=fig_size)

def plot_signal(time, signal, title='', xlab='', ylab='',
                line_width=1, alpha=1, color='k',
                subplots=False, show_grid=True, fig=f):

    # Skipping a lot of other complexity here

    axarr = f.add_subplot(1,1,1) # here is where you add the subplot to f
    plt.plot(time, signal, linewidth=line_width,
               alpha=alpha, color=color)
    plt.set_xlim(min(time), max(time))
    plt.set_xlabel(xlab)
    plt.set_ylabel(ylab)
    plt.grid(show_grid)
    plt.title(title, size=16)
    
    return(f)
f = plot_signal(time, signal, fig=f)
f
Run Code Online (Sandbox Code Playgroud)