Skip to content

Crash when interactively adding a number of subplots #11123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mdovgialo opened this issue Apr 25, 2018 · 6 comments
Closed

Crash when interactively adding a number of subplots #11123

mdovgialo opened this issue Apr 25, 2018 · 6 comments
Milestone

Comments

@mdovgialo
Copy link

Bug report

Bug summary

Adding subplots repeatedly to a figure in interactive mode can sometimes crash Matplotlib version 2.2.2, in version 2.0.2 everything works. Sometimes it does not crash, but when you resize figure's window to make it significantly smaller it crashes every time. I'm using Matplotlib on Kubuntu 16.04 64 bit with Python 3.5.2.

Code for reproduction

import matplotlib.pyplot as plt
import time

plt.ion()

def test_subplot_crash_with_matplotlib222():
    plt.ion()

    import matplotlib
    print("Matplotlib ver", matplotlib.__version__)
    fig = plt.figure()
    fig.set_size_inches(10, 10)
    for i in range(100):
        ax = fig.add_subplot(10, 10, i+1)
        ax.plot([0, 1], [0, 1])
        fig.tight_layout()
        fig.canvas.flush_events()
        print(i)
        time.sleep(0.01)
        if i == 25:
            fig.set_size_inches(3, 3)
    plt.ioff()
    plt.show()

if __name__ == '__main__':
    test_subplot_crash_with_matplotlib222()

Actual outcome

While adding 25th subplot it crashes. You can crash it earlier if you manually resize the window to make it smaller.

Traceback (most recent call last):
  File "tests/test_crash_matplotlib222.py", line 28, in <module>
    test_subplot_crash_with_matplotlib222()
  File "tests/test_crash_matplotlib222.py", line 18, in test_subplot_crash_with_matplotlib222
    ax = fig.add_subplot(10, 10, i+1)
  File "/home/marian/.local/lib/python3.5/site-packages/matplotlib/figure.py", line 1239, in add_subplot
    a = subplot_class_factory(projection_class)(self, *args, **kwargs)
  File "/home/marian/.local/lib/python3.5/site-packages/matplotlib/axes/_subplots.py", line 77, in __init__
    self._axes_class.__init__(self, fig, self.figbox, **kwargs)
  File "/home/marian/.local/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 488, in __init__
    raise ValueError('Width and height specified must be non-negative')
ValueError: Width and height specified must be non-negative

Expected outcome
Interactive matplotlib window with dynamically added 100 plots. While plots are being added window should be resizable. After 25'th plot it will make itself smaller in an effort to reproduce the bug. In Matplotlib version 2.0.2 it works without crashing.

Matplotlib version

  • Operating system: Kubuntu 16.04 64 bit, Linux 4.13.0-38-generic Fix git instructions on matplotlib.sf.net #43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Matplotlib version: 2.2.2
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.5.2

Installed matplotlib using:
pip3 install --user matplotlib==2.2.2

@jklymak
Copy link
Member

jklymak commented Apr 25, 2018

What happens if you turn off tight layout?

What does this look like in non crashing 2.0.2?

@mdovgialo
Copy link
Author

mdovgialo commented Apr 25, 2018

Hm, without tight_layout it doesn't crash in 2.2.2, but it shouldn't crash with tight_layout.

How does it look? A white window, in which plots are appearing, while the plots are appearing the window is resizable and those plots are being resized with the figure.

image

I'm using similar code for monitoring of online EEG signal. I add subplots on-line when new statistic is calculated and available. My code was crashing and I've narrowed down to this minimal example. I use tight_layout for so the plot titles and labels wouldn't overlap and screen space usage would be optimal.

@tacaswell tacaswell added this to the v2.2.3 milestone Apr 25, 2018
@QuLogic
Copy link
Member

QuLogic commented Apr 26, 2018

Pre-allocating is a bit safer, it seems:

    fig, axs = plt.subplots(10, 10, figsize=(10, 10))
    for ax in axs.flat:
        ax.set_visible(False)
    for i, ax in enumerate(axs.flat):
        ax.set_visible(True)
        ax.plot([0, 1], [0, 1])
        fig.tight_layout()
        fig.canvas.flush_events()
        print(i)
        time.sleep(0.01)
        if i == 25:
            fig.set_size_inches(3, 3)

does not crash as far as I can tell.

@mdovgialo
Copy link
Author

mdovgialo commented Apr 26, 2018

Pre-allocating is safer. But when you have 3 dynamic plots using all figure space, and then you collect enough data and want to show new plot, you have to use Axes.change_geometry method to make existing plots smaller and then add new subplot with newly calculated data. For now I'm staying with matplotlib 2.0.2

@jklymak
Copy link
Member

jklymak commented Jul 8, 2018

This is fixed in master #10915. Trying to backport to 2.2.3... The behaviour in master is to warn when tight_layout can't make the axes small enough anymore rather than giving a ValueError

@jklymak
Copy link
Member

jklymak commented Jul 8, 2018

Closed by #10915. Not sure it’s exacty what you wanted but at least it doesn’t crash. Thanks for the report.

@jklymak jklymak closed this as completed Jul 8, 2018
@QuLogic QuLogic modified the milestones: v2.2.3, v3.0 Jul 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants