Matplotlib重用另一个脚本创建的图形

时间:2017-02-21 12:35:28

标签: python matplotlib

我在MacOS上使用Matplotlib和Sulime Text。 我使用Python 3.5Matplotlib 2.0

当我处理图形时,我通常会有一个绘制数据的脚本,并将图形保存在带有plt.savefig()的.pdf文件中。然后我使用Skim(一个pdf查看器),以便每次修改和运行脚本时刷新文件。这允许我将我的工作布局设置为干净:脚本有一个窗口,一个窗口自动刷新。

我想保持相同的布局,但使用Matplotlib数字(因为它们是交互式的)。我正在寻找一种方法来使用plt.show(),但总是在同一个图中,这是我第一次运行脚本时创建的。

例如:

1。首次运行

import matplotlib.pyplot as plt
import numpy as np 

fig, ax = plt.figure()    

noise = np.random.rand(1, 100)
ax(noise)
plt.show()

2。以下运行

import matplotlib.pyplot as plt
import numpy as np 

# This is the super command I am looking for
fig = plt.get_previous_run_figure()
ax = fig.axes

noise = np.random.rand(1, 100)
ax.plot(noise)
plt.draw()

当然,在这种情况下,我必须与主脚本分开执行首次运行的脚本。有谁知道这是否可能?

3 个答案:

答案 0 :(得分:3)

您希望多个连续的python会话共享一个共同的Matplotlib窗口。我认为无法从单独的进程共享此窗口,尤其是当原始所有者可能在任何时间点终止时。

但是,您可以执行类似于当前工作流程的操作,在该工作流程中,您可以使用外部pdf查看器查看从多个python实例更新的输出文件。

有关如何挑选matplotlib数字,请参阅此问题/答案: Store and reload matplotlib.pyplot object

在每个脚本中,将matplotlib图输出为pickle对象,而不是调用plt.show():

import matplotlib.pyplot as plt
import numpy as np
import pickle

ax = plt.subplot(111)
x = np.linspace(0, 10)
y = np.exp(x)
plt.plot(x, y)
pickle.dump(ax, file('myplot.pickle', 'w'))

然后,启动一个专用的python会话,加载这个pickle对象并调用plt.show()。让这个脚本循环运行,检查磁盘上pickle文件的更新,并在必要时重新加载:

import matplotlib.pyplot as plt
import pickle

while True:
   ax = pickle.load(file('myplot.pickle'))
   plt.show()

替代

我没有单独的python会话,而是通常只有一个Ipython会话,我在其中运行不同的脚本。通过选择相同的数字窗口,我最终会得到一个与你描述的大致相似的设置,其中同一个图形窗口全天重复使用。

import matplotlib.pyplot as plt

fig = plt.figure(0)
fig.clf()

plt.show()

答案 1 :(得分:0)

原则上,可以使用系统范围的剪贴板在两个不同的脚本之间建立连接。 (据我所知,windows和macos中的剪贴板是系统范围的。)

因此,想法可以是使用tk或pyqt设置应用程序,并实现通用的FigureCanvas。此应用程序可以为剪贴板中的更改提供事件侦听器。

然后,另一个主工作流脚本将调用一些函数,该函数将当前图形包装到pickle对象中并将其发送到剪贴板,从GUI应用程序捕获它,在画布中显示为unpickled并显示。

这听起来像是一点点工作,但应该满足问题中非常严格的要求。

答案 2 :(得分:0)

Daan的替代方案为我工作。这里有更多的代码。我在Tkinter交互式GUI中使用它来重用/更新matplotlib图形窗口:

fig1 = None
if fig1:
    #if exists, clear figure 1
    plt.figure(1).clf() 
    plt.suptitle("New Fig Title", fontsize=18, fontweight='bold')
    #reuse window of figure 1 for new figure
    fig1 = plt.scatter(points.T[0], points.T[1], color='red', **plot_kwds)      
else:
    #initialize
    fig1 = plt.figure(num=1,figsize=(7, int(7*imgRatio)), dpi=80)
    plt.tick_params(axis='both', which='major', labelsize=14)
    plt.tick_params(axis='both', which='minor', labelsize=14)           
    plt.suptitle("Title", fontsize=18, fontweight='bold')
    fig1 = plt.scatter(points.T[0], points.T[1], color='red', **plot_kwds)

该图重用了(交互式)plt窗口。为此,我必须在matplotlibrc文件中设置interactive : True(请参阅我的评论here

相关问题