Reputation: 1244
I'm just starting using Matplotlib the "right" way. I'm writing various programs that will each give me back a time series, and I'm looking to superimpose the graphs of the various time series, like this:
I think what I want is a single Axes
instance defined in the main function, then I call each of my little functions, and they all return a Line2D
instance, and then I'll put them all on the Axes
object I created.
But I'm having trouble taking an existing Line2D
object and adding it to an existing Axes
object (like I'd want to do with the output of my function.) I thought of taking a Line2D
called a
and say ax.add_line(a)
.
import matplotlib.pyplot as plt
a, = plt.plot([1,2,3], [3,4,5], label = 'a')
fig, ax = plt.subplots()
ax.add_line(a)
Gives me a RuntimeError: "Can not put single artist in more than one figure."
I'm guessing that over time Matplotlib has stopped wanting users to be able to add a given line to any Axes
they want. A similar thing is discussed in the comments of this answer, except there they're talking about an Axes
object in two different Figure
objects.
What's the best way to accomplish what I want? I'd rather keep my main script tidy, and not say ax.plot(some_data)
over and over when I want to superimpose these lines.
Upvotes: 0
Views: 569
Reputation: 339290
Indeed, you cannot add the same artist to more than one axes or figure. But for what I understand from your question, that isn't really necessary.
So let's just do as you propose;
"I thought of taking a Line2D called a and say ax.add_line(a)."
import numpy as np
import matplotlib.pyplot as plt
def get_line(label="a"):
return plt.Line2D(np.linspace(0,1,10), np.random.rand(10), label = label)
fig, ax = plt.subplots()
ax.add_line(get_line(label="a"))
ax.add_line(get_line(label="b"))
ax.add_line(get_line(label="z"))
ax.legend()
plt.show()
The way matplotlib would recommend is to create functions that take an axes as input and plot to that axes.
import numpy as np
import matplotlib.pyplot as plt
def plot_line(ax=None, label="a"):
ax = ax or plt.gca()
line, = ax.plot(np.linspace(0,1,10), np.random.rand(10), label = label)
return line
fig, ax = plt.subplots()
plot_line(ax, label="a")
plot_line(ax, label="b")
plot_line(ax, label="z")
ax.legend()
plt.show()
Upvotes: 1
Reputation: 39052
A possible work around for your problem:
import matplotlib.pyplot as plt
x = np.array([1,2,3])
y = np.array([3,4,5])
label = '1'
def plot(x,y,label):
a, = plt.plot(x,y, label = label)
return a
fig, ax = plt.subplots()
plot(x,y,label)
plot(x,1.5*y,label)
You can put your plot
command now in a loop with changing labels
. You can still use the ax
handle to modify/define the plot parameters.
Upvotes: 0