Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib reuse figure created by another script

I am using Matplotlib on MacOS with Sulime Text. I use Python 3.5 and Matplotlib 2.0.

When I work on a figure, I usually have a script that plot the data, and save the figure in a .pdf file with plt.savefig(). Then I use Skim (a pdf viewer) in order to refresh the file each time I modify and run the script. This allows me to set my working layout as clean as: there is one window for the script, and one window for the figure which is automatically refreshing.

I would like to do keep the same layout, but using the Matplotlib figures (because they are interactive). I am looking for a way to use plt.show() but always in the same figure that has been created the first time I've run the script.

For instance:

1. First run

import matplotlib.pyplot as plt
import numpy as np 

fig, ax = plt.figure()    

noise = np.random.rand(1, 100)
ax(noise)
plt.show()

2. Following runs

import matplotlib.pyplot as plt
import numpy as np 

# This is the super command I am looking for
fig = plt.get_previous_run_figure()
ax = fig.axes

noise = np.random.rand(1, 100)
ax.plot(noise)
plt.draw()

In that case of course, I would have to do a first-run script separately from the main script. Does anyone know if it is possible ?

like image 583
Leonard Avatar asked Feb 21 '17 12:02

Leonard


1 Answers

You want to have multiple consecutive python sessions share a common Matplotlib window. I see no way to share this windows from separate processes, especially when the original owner may terminate at any point in time.

However, you could do something similar to your current workflow in which you have an external pdf viewer to view a output file which you update from multiple python instances.

See this question/answer on how to pickle a matplotlib figure: Store and reload matplotlib.pyplot object

In every script, output your matplotlib figure as a pickled object, rather than calling plt.show():

import matplotlib.pyplot as plt
import numpy as np
import pickle

ax = plt.subplot(111)
x = np.linspace(0, 10)
y = np.exp(x)
plt.plot(x, y)
pickle.dump(ax, file('myplot.pickle', 'w'))

Then, start a dedicated python session which loads this pickled object and calls plt.show(). Have this script run in a loop, checking for updates of the pickled file on disk, and reloading when necessary:

import matplotlib.pyplot as plt
import pickle

while True:
   ax = pickle.load(file('myplot.pickle'))
   plt.show()

Alternative

Instead of having separate python sessions, I usually have a single Ipython session in which I run different script. By selecting the same figure windows, I end up with a mostly similar setup as you describe, in which the same figure window is reused throughout the day.

import matplotlib.pyplot as plt

fig = plt.figure(0)
fig.clf()

plt.show()
like image 142
Daan Avatar answered Sep 20 '22 22:09

Daan