【问题标题】:Object-oriented pyplot面向对象的pyplot
【发布时间】:2016-05-15 04:34:16
【问题描述】:

我需要处理 pyplot 对象,例如图形和轴。这是我想要的一个简化示例:

In [1]: import matplotlib.pyplot as mp

In [2]: fig = mp.figure()             # create a figure

In [3]: mp.show()                     # and immediately show it. And close.

In [4]: ax = fig.add_subplot(111)     # Then I create a plot on that figure

In [5]: ax.plot([1, 2, 3]) 
Out[5]: [<matplotlib.lines.Line2D at 0x104e29a50>]

In [6]: mp.get_fignums()              # But I already released the figure, so it doesn't appear in the list of available figures
Out[6]: []

In [7]: fig.axes[0].lines[0].get_data()   # The data is there, on the plot
Out[7]: (array([ 0.,  1.,  2.]), array([1, 2, 3]))

In [8]: mp.show()                     # But mp.show() shows nothing.

fig.show() 也不起作用。释放后如何显示图形?

UPD:有一个类似的问题:Matplotlib: re-open a closed figure?,但没有答案。

【问题讨论】:

  • 为什么不从一个有效的matplotlib 示例开始?
  • 我很高兴有一个显示它的工作示例,如何获取已发布的数字。

标签: python matplotlib


【解决方案1】:

Which is the recommended way to plot: matplotlib or pylab? 问题与此问题相关。

pyplot 接口是一个便利模块,用于跟踪 a) 打开的图形和 b)“当前图形”和“当前轴”。下面是使用OO接口。

要拥有一个开放的图形并且能够在 repl 中输入新命令,您需要处于“交互”模式,该模式将 python repl 循环与 GUI 事件循环集成。

从您的问题看来,您使用的是 IPython,因此请使用 %matplotlib 魔法:

16:31 $ ipython
Python 3.5.1 |Continuum Analytics, Inc.| (default, Dec  7 2015, 11:16:01) 
Type "copyright", "credits" or "license" for more information.

IPython 4.2.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: %matplotlib
Using matplotlib backend: Qt4Agg

In [2]: import matplotlib.pyplot as plt

In [3]: fig, ax = plt.subplots()  # prompt returns immediatly leaving open figure

In [4]: ln, = ax.plot(range(15), label='test')  # draws line and updates figure

In [5]: ln.set_linewidth(5)  # changes lw and updates screen

In [6]: 

【讨论】:

    【解决方案2】:

    试试这个:

    import matplotlib.pyplot as mp
    
    fig = mp.figure()
    
    plt.show() # empty figure appears, close it
    
    fig = plt.gcf() # get current figure, this is the key piece.
    
    ax = fig.add_subplot(111) # added axes object
    
    ax.plot([1,2,3])
    
    plt.show()
    

    当我这样做时,我能够用绘制的对角线来显示情节。

    【讨论】:

    • 不幸的是,这是错误的。当您执行 plt.gcf() 时,您实际上创建了一个新图形并将这个新图形分配给旧变量 fig。这样你就失去了旧的形象。可以检查一下调用plt.gcf()前后无花果的地址是否不同
    【解决方案3】:

    我找到了!让我们创建一个 mp.Figure()

    import matplotlib.pyplot as mp
    fig = mp.Figure()
    

    现在它没有连接到pyplot,所以我们不能显示它。这相当于关闭图形时发生的情况。您无法显示未连接到 pyplot 的图形这一事实已得到充分证明。试试看

    In []: fig.show?
    Docstring:
    If using a GUI backend with pyplot, display the figure window.
    For non-GUI backends, this does nothing.
    

    (我减少了帮助消息的文本。) 但是有可能欺骗pyplot。让我们创建一个图形:

    temp_fig = mp.figure()
    

    从 temp_fig 中窃取图形管理器并将其分配给我们的 fig:

    m = mp.get_current_fig_manager()
    fig.canvas.manager = m
    

    现在我们可以展示它了:

    mp.show() # Shows the fig figure.
    

    当然,删除 temp_fig 是个好习惯:

    del temp_fig
    

    【讨论】:

    • 这使它变得比它需要的复杂得多。如果要创建Figure 对象,则还必须为其创建Canvas 对象。对于 GUI 后端,Canvas 对象是给定框架的“小部件”的子类,并且必须嵌入到 GUI 中,图形管理器为 pyplot 处理此问题。
    • 出于这些原因,我拒绝投票。请不要个人认为,我只是想通过一种比评论更强大的方法表明这个答案不是交互式使用 mpl 的推荐方式。
    猜你喜欢
    • 1970-01-01
    • 2014-08-25
    • 2010-10-22
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 1970-01-01
    相关资源
    最近更新 更多