How can plot Artists be reused (Line2D)?

  • The requested implementation in the OP doesn’t work because the Line2D plot Artist returned by plt.plot can’t be reused. Trying to do so, will result in a RuntimeError as per def set_figure(self, fig):
    • line1 in the OP, is not the same as line1 created directly with the Line2D method, because a plotted Artist has different properties.
    • In regards to seaborn, and API for matplotlib, axes-level plots like seaborn.lineplot return an axes:
      • p = sns.lineplot(...) then p.get_children() to get the Artist objects.
  • Plot artists can be created directly, with methods like matplotlib.lines.Line2D, and reused in multiple plots.
  • Updated code using standard importing practices, subplots, and not using a list-comprehension for a side-effect (a python anti-pattern).
  • Tested in 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()

enter image description here

Original Answer

  • Here is one possible solution. I’m not sure that it’s very pretty, but at least it does not require code duplication.
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()

Leave a Comment