I am trying to show the progress of a certain computation in python. I do this by issuing print statements but I would rather do that in a plot. I checked animation
of matplotlib but that requires an interval while in my case I want to "order" the plot to plot a new value in the plot. I thought that maybe the axes were persistent and I initiualized these once while successively adding plots, see below.
import numpy as np
import matplotlib.pyplot as plt
results =[
[ 0, 2.1899, 0.1399, 0.1297],
[ 100, 1.2034, 0.4417, 0.3743],
[ 200, 1.1814, 0.4810, 0.4194],
[ 300, 1.1407, 0.4705, 0.4116],
[ 400, 1.1278, 0.4937, 0.4224],
[ 500, 1.1185, 0.4976, 0.4136],
[ 600, 1.1002, 0.4885, 0.4194],
[ 700, 1.1596, 0.5046, 0.4263],
[ 800, 1.0914, 0.4304, 0.3870],
[ 900, 1.0824, 0.5129, 0.4322],
[1000, 1.0779, 0.5049, 0.4479],
[1100, 1.0579, 0.4849, 0.4322],
[1200, 1.0691, 0.5134, 0.4578],
[1300, 1.2005, 0.3770, 0.3330],
[1400, 1.0754, 0.5320, 0.4725],
[1500, 1.0534, 0.5283, 0.4676],
[1600, 1.0539, 0.5278, 0.4676],
[1700, 1.0420, 0.5427, 0.4921],
[1800, 1.0560, 0.5266, 0.4587],
[1900, 1.0551, 0.5076, 0.4470],
[2000, 1.0542, 0.5095, 0.4617],
[2100, 1.0436, 0.5200, 0.4607]]
def plot_init (data):
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.set_ylabel('Cost', color='r')
ax2.set_ylabel('Accuracy (train and test (dashed))', color='b')
ax2.set_ylim (0, 1)
return ax1, ax2
def plot_data (ax1, ax2, data, n):
ax1.plot(data [:n, 0], data [:n, 1], color = 'red', linewidth = 2)
maximum = int (max (data [:, 0]))
ax1.set_xlim(0, maximum)
ax1.set_ylim(bottom=0)
ax2.plot (data [:n, 0], data [:n, 2], color = 'blue')
ax2.plot (data [:n, 0], data [:n, 3], color = 'blue', linestyle = 'dashed')
plt.title("Cost and accuracy")
plt.show ()
data = np.array (results).reshape (22, 4)
axis_1, axis_2 = plot_init (data)
for i in range (10,20):
plot_data (axis_1, axis_2, data, i)
However, this generates 10 plots and only the first one contains a plot.
Does anyone have an idea how I can incrementally plot the results of my computation inside the same plot without having to create a new plot for each new result?
Edit
The solution of @user8153 worked well in another situation: to show a succeeding sequence of images in the same plot window. The code is shown below. I noticed that a plt.pause (0.5)
is crucial for it working correctly (0.5 may be 0.1 or even 0.01) because it appears that during that pause the image is being refreshed. In my case it didn't work without the call to pause
. Later on I decided to use a subplot to plot all 20 images into one plot. To see the image plotted as soon as it is ready a call to pause()
is necessary. Notice that @user8153 in his answer uses a call to pause()
as well. I hadn't paid much attention to it, until I started working with a sequence of images.
import numpy as np
import matplotlib.pyplot as plt
import time
import matplotlib.pyplot as plt
import numpy as np
def plot_init (data):
fig, ax1 = plt.subplots()
plt.title("Image")
image = plt.imshow (data)
return image
def plot_data (image, data, i):
plt.title("Image " + str (i))
image.set_data(data)
plt.draw()
data = np.random.rand(100, 100)
image = plot_init (data)
for i in range(10):
data = np.random.rand(100, 100)
plot_data (image, data, i)
plt.pause(0.5)
plt.show()