如何重用剧情艺术家(Line2D)?
问题描述
如何在后续绘图中重用.plot
中的绘图线?
我想在4个轴上绘制曲线图,前3个单独绘制在每个轴上,最后3个绘制在最后一个轴上。 代码如下:
from numpy import *
from matplotlib.pyplot import *
fig=figure()
data=arange(0,10,0.01)
ax1=fig.add_subplot(2,2,1)
ax2=fig.add_subplot(2,2,2)
ax3=fig.add_subplot(2,2,3)
ax4=fig.add_subplot(2,2,4)
line1=ax1.plot(data,data)
line2=ax2.plot(data, data**2/10, ls='--', color='green')
line3=ax3.plot(data, np.sin(data), color='red')
#could I somehow use previous plots, instead recreating them all?
line4=ax4.plot(data,data)
line4=ax4.plot(data, data**2/10, ls='--', color='green')
line4=ax4.plot(data, np.sin(data), color='red')
show()
结果图片为:
有没有一种方法可以先定义曲线图,然后将它们添加到轴上,然后再绘制它们?以下是我心目中的逻辑:
#this is just an example, implementation can be different
line1=plot(data, data)
line2=plot(data, data**2/10, ls='--', color='green')
line3=plot(data, np.sin(data), color='red')
line4=[line1, line2, line3]
现在在ax1上绘制line1,在ax2上绘制line2,在AX3上绘制line3,在ax4上绘制line4。
解决方案
- OP中请求的实现不起作用,因为
plt.plot
返回的Line2D
Plot Artist无法重用。尝试这样做,将按照def set_figure(self, fig):
产生RuntimeError
line1
在OP中,line1
与直接使用Line2D
方法创建的line1
不同,因为一个Plot Artist有不同的属性。- 对于
seaborn
和matplotlib
接口,像seaborn.lineplot
这样的轴级图返回一个axes
:p = sns.lineplot(...)
然后p.get_children()
获取Artist对象。
- 可以通过
matplotlib.lines.Line2D
等方法直接创建绘图艺术家,并在多个绘图中重复使用。 - 更新了代码,使用了标准导入做法、子图,而不是使用列表理解来获得副作用(Python反模式)。
- 测试于
python 3.8.11
,matplotlib 3.4.3
import numpy as np
from copy import copy
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
# crate the figure and subplots
fig, axes = plt.subplots(2, 2)
# flatten axes into 1-D for easy indexing and iteration
axes = axes.ravel()
# test data
data=np.arange(0, 10, 0.01)
# create test lines
line1 = Line2D(data, data)
line2 = Line2D(data, data**2/10, ls='--', color='green')
line3 = Line2D(data, np.sin(data), color='red')
lines = [line1, line2, line3]
# add the copies of the lines to the first 3 subplots
for ax, line in zip(axes[0:-1], lines):
ax.add_line(copy(line))
# add 3 lines to the 4th subplot
for line in lines:
axes[3].add_line(line)
# autoscale all the subplots if needed
for _a in axes:
_a.autoscale()
plt.show()
原始答案
- 这里有一个可能的解决方案。我不确定它是否很漂亮,但至少它不需要代码重复。
import numpy as np, copy
import matplotlib.pyplot as plt, matplotlib.lines as ml
fig=plt.figure(1)
data=np.arange(0,10,0.01)
ax1=fig.add_subplot(2,2,1)
ax2=fig.add_subplot(2,2,2)
ax3=fig.add_subplot(2,2,3)
ax4=fig.add_subplot(2,2,4)
#create the lines
line1=ml.Line2D(data,data)
line2=ml.Line2D(data,data**2/10,ls='--',color='green')
line3=ml.Line2D(data,np.sin(data),color='red')
#add the copies of the lines to the first 3 panels
ax1.add_line(copy.copy(line1))
ax2.add_line(copy.copy(line2))
ax3.add_line(copy.copy(line3))
[ax4.add_line(_l) for _l in [line1,line2,line3]] # add 3 lines to the 4th panel
[_a.autoscale() for _a in [ax1,ax2,ax3,ax4]] # autoscale if needed
plt.draw()
相关文章