我有一个脚本,可以根据数据生成matplotlib数据。这些图按如下方式保存到磁盘:
fig, ax = plt.subplots()
# create the plot
# ...
pickle.dump(ax, open(of, 'wb'))
在另一个脚本中,我想加入某些这些情节。我可以使用以下方式读取数据:
figures = [pickle.load(file) for file in files]
(FWIW,我读回的数据的类型为AxesSubplot
。)
到目前为止一切顺利。现在我想使用可用图的最大或最小比例将两个(或更多)数字的数据放在一起。由于我缺乏经验,我完全不知道如何实现这一目标。我确实找到了关于加入情节的问题,并且共识是首先在一个图中绘制。在我的情况下,由于单个数据集的绘图逻辑已经非常复杂,因此相当困难。 (还有其他原因可以解释为什么每个数据集应该在第一步中独立绘制,然后才可能与其他数据集联合起来。)
我想要加入的图表以相同的方式表示他们的数据 - 即所有图都是线图或直方图(不确定如何有意义地加入这些图)或QQPlots(参见statsmodels.api)。它们可能具有或不具有相同大小的数据。
如何加入不同数字的情节?
答案 0 :(得分:3)
我认为您会发现将数据保存到以后可以生成新图表的文件更容易。你甚至可以使用np.savez
不仅保存数据,还将plot方法及其参数保存在一个文件中。以下是您以后load这些文件在新图中生成“已加入”图的方法:
import matplotlib.pyplot as plt
import numpy as np
def join(ax, files):
data = [np.load(filename) for filename in files]
for datum in data:
method = getattr(ax, datum['method'].item())
args = tuple(datum['args'])
kwargs = datum['kwargs'].item()
method(*args, **kwargs)
x = np.linspace(-3, 3, 100)
y = np.exp(-x**2/2)/np.sqrt(2*np.pi)
a = np.random.normal(size=10000)
fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()
np.savez('/tmp/a.npz', method='plot', args=(x, y), kwargs=dict())
fig, ax = plt.subplots()
ax.hist(a, bins=100, density=True)
plt.show()
np.savez('/tmp/b.npz', method='hist', args=(a,),
kwargs=dict(bins=100, density=True))
fig, ax = plt.subplots()
join(ax, ['/tmp/a.npz', '/tmp/b.npz'])
plt.show()
上面我使用np.savez
和np.load
代替pickle
来保存和恢复数据。或者,您可以选择包含数据,方法及其参数的字典,元组或列表。但是,由于数据主要是数字,因此np.savez
使用more efficient and less of a security risk than pickle。
答案 1 :(得分:3)
您通常会将绘图放入一个函数中,该函数将轴绘制为参数。然后,您可以随意重复使用此功能。
import numpy as np
import matplotlib.pyplot as plt
def myplot1(data, ax=None, show=False):
if not ax:
_, ax = plt.subplots()
ax.plot(data[0], data[1])
if show:
plt.show()
def myplot2(data, ax=None, show=False):
if not ax:
_, ax = plt.subplots()
ax.hist(data, bins=20, density=True)
if show:
plt.show()
x = np.linspace(-3, 3, 100)
y = np.exp(-x**2/2)/np.sqrt(2*np.pi)
a = np.random.normal(size=10000)
# create figure 1
myplot1((x,y))
#create figure 2
myplot2(a)
# create figure with both
fig, ax = plt.subplots()
myplot1((x,y), ax=ax)
myplot2(a, ax=ax)
plt.show()
<小时/>
要回答这个问题,是的,你可以将艺术家从一个未经修饰的人物中移开,但这涉及到一些黑客行为并可能导致不完美的结果:
import matplotlib.pyplot as plt
import numpy as np
import pickle
x = np.linspace(-3, 3, 100)
y = np.exp(-x**2/2)/np.sqrt(2*np.pi)
a = np.random.normal(size=10000)
fig, ax = plt.subplots()
ax.plot(x, y)
pickle.dump(fig, open("figA.pickle","wb"))
#plt.show()
fig, ax = plt.subplots()
ax.hist(a, bins=20, density=True, ec="k")
pickle.dump(fig, open("figB.pickle","wb"))
#plt.show()
plt.close("all")
#### No unpickle the figures and create a new figure
# then add artists to this new figure
figA = pickle.load(open("figA.pickle","rb"))
figB = pickle.load(open("figB.pickle","rb"))
fig, ax = plt.subplots()
for figO in [figA,figB]:
lists = [figO.axes[0].lines, figO.axes[0].patches]
addfunc = [ax.add_line, ax.add_patch]
for lis, func in zip(lists,addfunc):
for artist in lis[:]:
artist.remove()
artist.axes=ax
artist.set_transform(ax.transData)
artist.figure=fig
func(artist)
ax.relim()
ax.autoscale_view()
plt.close(figA)
plt.close(figB)
plt.show()
在这里,我们循环遍历未打印的图形中的所有线条和补丁,将它们从旧图形中移除并将它们添加到新图形中。为此,我们需要设置轴,变换和图形以正确匹配新图形。 这当然会越来越复杂,图中有更多不同类型的艺术家,需要even more complex methods if those artists have transforms other than the data transform associated with them。