您可以仅将一些子图复制到新图形吗?

时间:2019-03-29 14:45:02

标签: python matplotlib seaborn

是否可以将轴(子图)复制到新图形? 在其他语言中,这很简单,但是我知道,即使深度复制也无法与python的matplotlib一起使用。 例如。如果我有一个包含6个子图的图形,如何将所有设置将这些子图形中的2个复制到一个新图形中?标签,刻度线,图例,网格等。

我发现了这个answer,它实际上是2比1:第一个不再有效(不赞成使用的语法),而我却无法使用第二个。

我设法重新创建了一个新图形并删除了不需要的子图,但是我剩下了一个3x2的子图网格,其中绘制了2个,其中4个为空。 有什么建议吗?

我在下面整理了一个玩具示例;我的图表当然会随着设置的增加而变得更加复杂。

请注意,我使用的是seaborn,但应该无关紧要-我相信这是一个matplotlib问题,无论是否使用seaborn,答案都将相同。

更新:按照@Earnest的提示,我可以更改新图形的几何形状,使其仅具有两个子图,

axes.change_geometry(1,2,2)

我不知道该怎么做是将子图移动。回顾一下:

  • 我从3x2网格中的6个子图开始。
  • 我腌制记忆,然后腌制成一个新的人物。
  • 在新图中,我仅保留子图1和2,即用[行,列] [0,1]和[1,0]标识的子图;其他4个子图现在是空白。
  • 我想要一个[1x2]网格布局;如果我执行axes.change_geometry(1,2,2),则可以得到该布局,但是我的两个子图之一将消失。

有什么建议吗?

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib
    import seaborn as sns
    import pickle
    import io


    sns.set(style='darkgrid')

    n=int(100)
    x=np.arange(0,n)

    fig, ax = plt.subplots(3,2)

    for i,a in enumerate(ax.flatten() ):
        y= np.random.rand(n)
        sns.lineplot( x, y , ax =a )
        a.set_title('Chart # ' + str(i+1))
        a.set_xlabel('my x')
        a.set_ylabel('my y')

    fig2, ax2 = plt.subplots(1,2)

    buf = io.BytesIO()
    pickle.dump(fig, buf)
    buf.seek(0)

    fig2=pickle.load(buf)

    tokeep=[1,2]

    # note that i == 1correponds to a[0,1]
    for i,a in enumerate(fig2.axes):
        if not i in(tokeep):
            fig2.delaxes(a)
        else:
            axes=a

1 个答案:

答案 0 :(得分:0)

这真的是@Ernest的答案;他向我指出了正确的方向。我在这里输入此内容作为将来的参考,希望它对其他人有用。基本上,在删除不需要的子图后,我必须使用change_geometry。我认为R Universe中的ggplot具有更清晰的实现,但是,总体而言,这似乎还可以-不太麻烦。 我已经注释了下面的代码-希望它足够清楚:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pickle
import io

sns.set(style='darkgrid')

#create the subplots
n=int(100)
x=np.arange(0,n)
fig, ax = plt.subplots(3,2)

for i,a in enumerate(ax.flatten() ):
    y= np.random.rand(n)
    sns.lineplot( x, y , ax =a )
    a.set_title('Chart # ' + str(i+1))
    a.set_xlabel('my x')
    a.set_ylabel('my y')

# pickle the figure, then unpickle it to a new figure
buf = io.BytesIO()
pickle.dump(fig, buf)
buf.seek(0)
fig2=pickle.load(buf)

# sets which subplots to keep
# note that i == 1correponds to a[0,1]
tokeep=[1,2]
axestokeep=[]

for i,a in enumerate(fig2.axes):
    if not i in(tokeep):
        fig2.delaxes(a)
    else:
        axestokeep.extend([a])

axestokeep[0].change_geometry(1,2,1)
axestokeep[1].change_geometry(1,2,2)