How to keep the previous plot and not clear the figure after calling plt.show() without simply repeating the call?

Viewed 1397
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
plt.plot(x, np.sin(x))
plt.show()
plt.plot(x, np.cos(x))
plt.show()

This example produces two consecutive plots in two windows, first the one on the left, then the one on the right:

Figure 1

As you can see, the sine disappeared and only the cosine shows up in the second window; the plot window has been cleared in between. However, this is what I want:

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
plt.plot(x, np.sin(x))
plt.show()
plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
plt.show()

Figure 2

How can I keep the previous plot so it shows up in the second plot, too? There has to be a better way other than simply repeating the previous call to plt.plot?

1 Answers

(A) Repeat previous calls to plt.plot: Just as mentioned in the question, it's possible to just repeat the previous calls which created the plots before adding the new plot. This might be the easiest solution for simple cases.

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
plt.plot(x, np.sin(x))
plt.show()
plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
plt.show()

(B) Use plt.waitforbuttonpress: If this is applicable in your case, you can use plt.waitforbuttonpress as an interrupt between plots which waits for a mouse click or key press until the next plot is added into the same window.

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
for f in [np.sin, np.cos]:
    plt.plot(x, f(x))
    plt.waitforbuttonpress()

(C) Pickle the plot before plt.show: I don't know how well this works for complex plots, but it seems possible to pickle the plot before calling plt.show, only to immediately restore it afterwards. Then the additional plot can be added before the next call to plt.show.

import matplotlib.pyplot as plt
import numpy as np
import pickle
x = np.linspace(0, 2 * np.pi, 100)
ax = plt.gca()
for f in [np.sin, np.cos]:
    plt.plot(x, f(x))
    temp = pickle.dumps(ax)
    plt.show()
    ax = pickle.loads(temp)

(D) Manipulating figure manager and canvas: Essentially, the figure fig gets "loaded into" a newly created figure for each loop iteration, then updated with new plots.

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
fig = plt.figure()
plt.close()
for f in [np.sin, np.cos]:
    plt.figure()
    fm = plt.get_current_fig_manager()
    fm.canvas.figure = fig
    fig.canvas = fm.canvas
    plt.plot(x, f(x))
    plt.show()
    plt.close()
Related