在 matplotlib 中的单独图中绘制子图轴 [英] Plot subplot axes in separate figure in matplotlib
问题描述
假设我有以下代码(
如何提取"ax5
并将其全屏"绘制在单独的图形中而不必重新创建绘图?
我在官方文档中找不到任何内容来支持我所说的内容,但我的理解是不可能克隆"现有的轴到一个新的数字.实际上,不能将在一个轴上定义的艺术家(线条,文字,图例)添加到另一个轴上.Github 上的这个讨论可能在一定程度上解释了它.
例如,尝试从 fig1
上定义的轴添加一条线到不同图形 fig2
上的轴会引发错误:
将matplotlib.pyplot导入为plt图1 = plt.figure()ax1 = fig1.add_subplot(111)行,= ax1.plot([0,1])fig2 = plt.figure()ax2 = fig2.add_subplot(111)ax2.add_line(line)>>> RuntimeError:不能将一个艺术家放在一个以上的图中.
尝试在相同图上将在 ax1
中绘制的线添加到第二个轴 ax2
上会产生错误:>
fig1 = plt.figure()ax1 = fig1.add_subplot(121)线, = ax1.plot([0,1])ax12 = fig1.add_subplot(122)ax12.add_line(line)>>>ValueError: 无法重置轴.您可能正在尝试在多个不受支持的 Axes 中重复使用艺术家
我能提出的最佳建议是从您要复制的轴中提取数据,然后手动将其绘制到一个大小符合您喜好的新轴对象中.像下面这样的东西证明了这一点.请注意,这适用于通过 ax.plot
绘制的 Line2D
对象.如果数据是使用 ax.scatter
绘制的,则只需稍作更改,我请参阅您在此处了解有关如何从散点图中提取数据的说明.
将matplotlib.pyplot导入为plt将numpy导入为npdef rd(n = 5):# 制作随机数据返回 np.sort(np.random.rand(n))图1 = plt.figure()ax1 = fig1.add_subplot(111)#在一个轴上绘制三条线ax1.plot(rd(), rd(), rd(), rd(), rd(), rd())xdata = []ydata = []# 遍历行并提取 x 和 y 数据对于 ax1.get_lines() 中的行:xdata.append( line.get_xdata() )ydata.append( line.get_ydata() )# 新建图形并绘制提取的数据fig2 = plt.figure()ax2 = fig2.add_subplot(111)对于 zip(xdata,ydata) 中的 X,Y:ax2.plot(X,Y)
希望有帮助.
Suppose I have the following code (modified version of matplotlib gridspec tutorial)
import matplotlib.pyplot as plt
def make_ticklabels_invisible(fig):
for i, ax in enumerate(fig.axes):
ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
for tl in ax.get_xticklabels() + ax.get_yticklabels():
tl.set_visible(False)
plt.figure(0)
ax1 = plt.subplot2grid((3,3), (0,0), colspan=3)
ax2 = plt.subplot2grid((3,3), (1,0), colspan=2)
ax3 = plt.subplot2grid((3,3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3,3), (2, 0))
plt.subplot2grid((3,3), (2, 1)) # OOPS! Forgot to store axes object
plt.suptitle("subplot2grid")
make_ticklabels_invisible(plt.gcf())
plt.show()
which results in
How can I 'extract' ax5
and plot it 'full screen' in a separate figure without having to recreate the plot?
I can't find anything in official documentation to back up what I'm saying, but my understanding is that it is impossible to "clone" an existing axes onto a new figure. In fact, no artist (line, text, legend) defined in one axes may be added to another axes. This discussion on Github may explain it to some degree.
For example, attempting to add a line from an axes defined on fig1
to an axes on a different figure fig2
raises an error:
import matplotlib.pyplot as plt
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
line, = ax1.plot([0,1])
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.add_line(line)
>>>RuntimeError: Can not put single artist in more than one figure`
And attempting to add a line that was drawn in ax1
to a second axes ax2
on the same figure raises an error:
fig1 = plt.figure()
ax1 = fig1.add_subplot(121)
line, = ax1.plot([0,1])
ax12 = fig1.add_subplot(122)
ax12.add_line(line)
>>>ValueError: Can not reset the axes. You are probably trying to re-use an artist in more than one Axes which is not supported
The best recommendation I can make is extract the data from the axes you want to copy, and manually plot that into a new axes object that is sized to your liking. Something like below demonstrates this. Note that this works for Line2D
objects plotted via ax.plot
. If the data was plotted using ax.scatter
, then you need to change things just a little bit and I refer you here for instructions on how to extract data from a scatter.
import matplotlib.pyplot as plt
import numpy as np
def rd(n=5):
# Make random data
return np.sort(np.random.rand(n))
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
# Plot three lines on one axes
ax1.plot(rd(), rd(), rd(), rd(), rd(), rd())
xdata = []
ydata = []
# Iterate thru lines and extract x and y data
for line in ax1.get_lines():
xdata.append( line.get_xdata() )
ydata.append( line.get_ydata() )
# New figure and plot the extracted data
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
for X,Y in zip(xdata,ydata):
ax2.plot(X,Y)
Hope it helps.
这篇关于在 matplotlib 中的单独图中绘制子图轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!