您可以只将一些子图复制到新图形中吗? [英] Can you copy only some subplots to a new figure?
问题描述
有没有办法将轴(子图)复制到新图形中?这在其他语言中很简单,但我知道即使是深拷贝也不适用于 python 的 matplotlib.例如.如果我有一个包含 6 个子图的图形,我如何将这些子图中的 2 个复制到一个新图形中,并带有所有设置?标签,刻度线,图例,网格等.
Is there a way to copy an axis (subplot) to a new figure? This is straightforward in other languages, but I understand that not even a deep copy would work with python's matplotlib. E.g. if I have a figure with 6 subplots, how can I copy 2 of those subplots to a new figure, with all the settings? Labels, tickmarks, legend, grid, etc.
我发现这个 answer ,实际上是二合一:第一个不再有效(不推荐使用的语法),而我无法让第二个在我的情况下工作.
I have found this answer , which is actually 2 in 1: the first no longer works (deprecated syntax), while I couldn't get the second to work in my case.
我设法重新创建了一个新图形并删除了我不想要的子图,但是我留下了一个 3x2 的子图网格,其中绘制了 2 个,4 个为空.有什么建议吗?
I manage to recreate a new figure and to remove the subplots I don't want, but I am left with a 3x2 grid of subplots, in which 2 are drawn and 4 are empty. Any suggestions?
我在下面整理了一个玩具示例;当然,我的图表更复杂,设置更多.
I have put together a toy example below; my charts are, of course, way more complex with way more settings.
请注意,我使用的是seaborn,但应该无关紧要-我相信这是一个matplotlib问题,无论是否使用seaborn,答案都将是相同的.
Note I used seaborn but it should be irrelevant - I believe this is a matplotlib question and the answer is going to be the same regardless of whether seaborn is used.
更新:按照@Earnest 的提示,我可以更改新图形的几何形状,使其只有两个子图,执行:
UPDATE: Following the tips from @Earnest, I can change the geometry of the new figure so that it only has two subplots, doing:
axes.change_geometry(1,2,2)
我不知道该怎么做是将子图移动.回顾一下:
What I don't know how to do is to move the subplots around. To recap:
- 我从3x2网格中的6个子图开始.
- 我回忆起记忆,然后解开一个新的人物.
- 在新图中,我只保留子图 1 和 2,即由 [行,列] [0,1] 和 [1,0] 标识的那些;其他 4 个子图现在是空白区域.
- 我想要一个 [1x2] 的网格布局;如果我做
axes.change_geometry(1,2,2)
然后我得到那个布局,但我的两个子图之一消失了.
- I start with 6 subplots in a 3x2 grid.
- I pickle to memory, then unpickle to a new figure.
- In the new figure, I keep only subplots 1 and 2, i.e. those identified by [rows, columns] [0,1] and [1,0]; the other 4 subplots are now blank spaces.
- I want a [1x2] grid layout; if I do
axes.change_geometry(1,2,2)
then I get that layout, but one of my two subplots disappears.
有什么建议吗?
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
推荐答案
这真的是@Ernest的答案;他向我指出了正确的方向.我在这里输入此内容作为将来的参考,希望它对其他人有用.基本上我必须在删除我不需要的子图后使用 change_geometry .我认为R Universe中的ggplot具有更简洁的实现,但是,总体而言,这似乎还可以-不太麻烦.我已经评论了下面的代码 - 希望它足够清楚:
This is really @Ernest's answer; he pointed me in the right direction. I am typing this here as an answer for future reference, in the hope it can be useful to others. Basically I had to use change_geometry after deleting the subplots I didn't need. I think ggplot in the R universe has a cleaner implementation, but, overall, this seems OK - not too cumbersome. I have commented the code below - hope it's clear enough:
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)
这篇关于您可以只将一些子图复制到新图形中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!