1

I would like to update a figure of matplotlib for every iteration in a loop. It works for about the first 30 iterations, but then the updates stop although there are more iterations.

Following you can find my code for the figure:

import numpy as np
import matplotlib.pyplot as plt


class SimpOutput:
    fig = None
    ax_l = None
    ax_r = None

    it_container = []
    obj_container = []

    def __init__(self):
        self.fig, (self.ax_l, self.ax_r) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))
        self.ax_l.set_title("Flexibility $c$")
        self.ax_l.set_ylabel("obj. value $c$")
        self.ax_l.set_xlabel("Iteration")

        self.ax_r.set_title("Shape")

        self.fig.show()

    def update(self, iteration, obj, x):

        self.it_container.append(iteration)
        self.obj_container.append(obj)

        self.ax_l.plot(self.it_container, self.obj_container, c="r")

        x = x.reshape((4, 4))
        x = x.T
        x = np.flip(x, 0)
        self.ax_r.imshow(x, cmap="binary")
        plt.pause(0.1)
        self.fig.show()
        plt.pause(0.1)

if __name__ == "__main__":
    out = SimpOutput()

    for i in range(50):

        out.update(i, 1000 * np.random.rand(), np.random.rand(16))

update is called in every loop.

Using fig.canvas.show() and different values for pause does not affect on the update. Furthermore, the methods set_array() and set_data() do not fix the problem either. While debugging, the figure is updated for every iteration. I write the code with PyCharm.

Does anyone had the same issue or rather does anyone has an idea how to solve this issue?

Thanks in advance!

Bests,

Sebastian

Klixz
  • 13
  • 3

1 Answers1

0

I tried to run the following simple code:

for i in range(50):
    plt.clf()
    pd.DataFrame([3,4,i]).plot.line(title=f'iteration {i}')
    plt.show()

Not updating any figure, just clearing the old one and plotting a new figure.

It stops creating new figures after 30 iterations as well. Same problem as you.

I suspected the problem is in pycharm, so I tried one more thing.

I replaced plt.show() with plt.savefig(f'example_{i}.jpg'). It indeed saved all 50 figures in the folder (means it worked okay), and in addition, it gave me a warning:

envs\my_main_env\lib\site-packages\pandas\plotting\_matplotlib\core.py:337: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
  fig = self.plt.figure(figsize=self.figsize)

indicating the problem is in the number of figures open at parallel. You can google the warning find some answers to it (e.g. warning about too many open figures).

I added the parameter at the beginning of the code: plt.rcParams.update({'figure.max_open_warning': 60})

now, running again. In pycharm in scientific mode, it didn't work. So I turned off scientific mode (opening a new figure for each plot) and now it works well! so I think that the limitation is a pycharm limitation for scientific mode - how many figures can be open at the same time.

turn off scientific mode for plotting by going to Settings->Tools->Python Scientific-> uncheck "Show plots in tool window" box.

That worked for me. I don't know how to change the limit in scientific mode (if possible at all). I believe it gives enough insights for you to solve your issue - whether by saving the figures or by plotting them without scientific mode.

Roim
  • 2,986
  • 2
  • 10
  • 25
  • 1
    Thanks for the quick and detailed answer. I am very grateful to you. Unchecking "Show plots in tool window" works very well in my case. – Klixz Sep 15 '21 at 13:04