如何加入两个matplotlib人物

Max*_*rch 2 matplotlib python-3.x

我有一个脚本,可从数据生成matplotlib数字。这些图将保存到磁盘,如下所示:

fig, ax = plt.subplots() # create the plot # ... pickle.dump(ax, open(of, 'wb'))

在另一个脚本中,我想加入其中某些情节。我可以使用以下方式读取数据:

figures = [pickle.load(file) for file in files]

(FWIW,我读回的数字带有类型AxesSubplot。)

到目前为止,一切都很好。现在,我想使用可用图的最大或最小比例将两个(或多个)图形的数据放在一起。由于缺乏经验,我完全不知道如何实现这一目标。我确实发现了有关加入地块的问题,并且共识是首先绘制一个图形。在我的情况下,这将非常困难,因为单个数据集的绘制逻辑已经很复杂。(还有其他原因,为什么每个数据集都应首先自己绘制,然后才可能与其他数据集连接)。

我要加入的图以相同的方式表示其数据-即所有图都是线图或直方图(不确定要如何有效地连接那些图)或QQPlot(请参阅statsmodels.api)。它们可能具有或可能不具有相同的数据大小。

如何加入不同数字的地块?

Imp*_*est 6

创建函数以绘制到特定轴

您通常会将绘图放入一个函数中,该函数将要绘制的轴作为参数。然后,您可以随心所欲地重用此功能。

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()
Run Code Online (Sandbox Code Playgroud)


将艺术家转移到新形象

要回答这个问题,是的,您可以从未腌制的图形中移动艺术家,但这涉及一些黑客行为,可能会导致不完美的结果:

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()
Run Code Online (Sandbox Code Playgroud)

在这里,我们遍历未腌制图形中的所有线条和补丁,将它们从旧图形中删除并将它们添加到新图形中。为此,我们需要设置轴、变换和图形以正确匹配新图形。这当然会变得越来越复杂,因为图中的艺术家种类越多,如果这些艺术家有与他们关联的数据变换以外的变换,则需要更复杂的方法


unu*_*tbu 5

我认为您会发现将数据保存到文件中更容易,以后可以从该文件中生成新图。您甚至可以使用np.savez它不仅将数据保存,还将plot方法及其参数保存在一个文件中。这是您以后如何加载这些文件以在新图中生成“连接”图的方式:

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


上面我使用np.saveznp.load不是pickle保存和还原数据。或者,您可以腌制包含数据,方法及其参数的字典,元组或列表。但是,由于数据主要是数字数据,np.savez因此与pickle相比,使用效率更高,并且安全风险较小