在matplotlib中保存show()之后的fig内容?

2024-04-24 05:48:32 发布

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

我正在创建一些数据的violinplot,然后我将一个带有单个数据点(示例中的红点)的散点图渲染为三个子图。你知道吗

enter image description here

由于violinplot的生成相对耗时,所以我只生成一次violinplot,然后为一个数据行添加散点图,写入结果文件,从轴上删除散点图,然后为下一行添加散点图。你知道吗

一切正常,但我想添加一个选项,在保存每个绘图之前显示()。你知道吗

如果我使用的是plt.show(),那么图是正确显示的,但是之后图似乎被清除了,在下一次迭代中,我得到的是没有小提琴图的图。你知道吗

有没有什么办法可以保存图片的内容节目()? 你知道吗

简而言之,我的代码是

fig = generate_plot(ws, show=False) #returns the fig instance of the violin plot

#if I do plt.show() here (or in "generate_plot()"), the violin plots are gone.

ax1, ax3, ax2 = fig.get_axes()
scatter1 = ax1.scatter(...) #draw scatter plot for first axes
[...] #same vor every axis
plt.savefig(...)
scatter1.remove()

Tags: the数据示例plotshowfigpltgenerate
3条回答

我在想一个可能的选择是使用事件循环来推进情节。下面将定义一个更新函数,该函数仅更改散点、绘制图像并保存图像。我们可以通过一个类来管理这个问题,该类在按键上有一个回调,这样当你点击空格时,就会显示下一幅图像;在最后一幅图像上按空格时,绘图就会关闭。你知道吗

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np

class NextPlotter(object):
    def __init__(self, fig, func, n):
        self.__dict__.update(locals())
        self.i = 0
        self.cid = self.fig.canvas.mpl_connect("key_press_event", self.adv)

    def adv(self, evt):
        if evt.key == " " and self.i < self.n:
            self.func(self.i)
            self.i+=1
        elif self.i >= self.n:
            plt.close("all")

#Start of code:
# Create data
pos = [1, 2, 4, 5, 7, 8]
data = [np.random.normal(0, std, size=100) for std in pos]
data2 = [np.random.rayleigh(std, size=100) for std in pos]
scatterdata = np.random.normal(0, 5, size=(10,len(pos)))

#Create plot
fig, axes = plt.subplots(ncols=2)

axes[0].violinplot(data, pos, points=40, widths=0.9,
                      showmeans=True, showextrema=True, showmedians=True)
axes[1].violinplot(data2, pos, points=40, widths=0.9,
                      showmeans=True, showextrema=True, showmedians=True)

scatter = axes[0].scatter(pos, scatterdata[0,:], c="crimson", s=60)
scatter2 = axes[1].scatter(pos, scatterdata[1,:], c="crimson", s=60)  

# define updating function
def update(i):
    scatter.set_offsets(np.c_[pos,scatterdata[2*i,:]])
    scatter2.set_offsets(np.c_[pos,scatterdata[2*i+1,:]])
    fig.canvas.draw()
    plt.savefig("plot{i}.png".format(i=i))

# instantiate NextPlotter; press <space> to advance to the next image        
c = NextPlotter(fig, update, len(scatterdata)//2)

plt.show()

一个解决方法是不删除散点图。你知道吗

为什么不保留散点图坐标轴,只更新该坐标轴集的数据?你知道吗

更新散点图数据后,很可能需要plt.draw()来强制进行新的渲染。你知道吗

我找到了一种交互绘制图形的方法hereplt.ion()并用input()阻止进程似乎很重要。你知道吗

import matplotlib.pyplot as plt
plt.ion()

fig = plt.figure()
ax = plt.subplot(1,1,1)
ax.set_xlim([-1, 5])
ax.set_ylim([-1, 5])
ax.grid('on')

for i in range(5):
    lineObject = ax.plot(i,i,'ro')
    fig.savefig('%02d.png'%i)
    # plt.draw() # not necessary?
    input()
    lineObject[0].remove()

我还试图用time.sleep(1)阻止这个进程,但它根本不起作用。你知道吗

相关问题 更多 >