Skip to content

Windows are not shown with Tk + interactive mode, from matplotlib 3.4 #19935

Open

Description

@kngwyu

Bug report

Bug summary

The behavior of Tk backend in interactive mode has changed. My code depends on the old behavior and does not work with matplotlib 3.4.

Code for reproduction

import time

import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt


def test_heatmap_draw():
    mpl.use("TkAgg")
    plt.ion()

    DATA_SHAPE = 10, 10
    fig = plt.figure()
    ax = fig.add_subplot()
    img = ax.imshow(np.zeros(DATA_SHAPE), vmin=-1, vmax=1)

    for _ in range(10):
        img.set_data(np.random.uniform(-1, 1, DATA_SHAPE))
        fig.canvas.draw()
        time.sleep(0.1)


if __name__ == "__main__":
    test_heatmap_draw()

Actual outcome
No windows are shown with matplotlib >= 3.4.
I guess that #17789 is the trigger. Inserting self._master.update_idletasks worked, like:

class FigureCanvasTkAgg(FigureCanvasAgg, FigureCanvasTk):
    def draw(self):
        super().draw()
        self.blit()
        self._master.update_idletasks()

Expected outcome
The heatmap is interactively updated with matplotlib 3.3.4.

BTW, thank you for encouraging me on twitter.

Activity

  1. richardsheridan commented on Apr 11, 2021

    @richardsheridan
    Contributor

    My opinion is that this is the intended behavior. It is harmful to call update_idletasks or update in TCL library code for the reasons mentioned in that issue. However, client code should be free to use it. In this case the appropriate api, since you are driving your own event loop, is figure.canvas.flush_events which just calls update but in a backend-agnostic way.

    Updating the docs would be very nice, I'll help where I can!

  2. kngwyu commented on Apr 12, 2021

    @kngwyu
    Author

    @richardjgowers
    Thank you for your help! That makes sense.

    For documents, I think the Explicitly spinning the Event Loop is enough good, but I feel the more entry-level description of interactive mode is somewhat confusing.
    It says that:

    If in interactive mode:
    - newly created figures will be displayed immediately
    - figures will automatically redraw when elements are changed
    - pyplot.show() displays the figures and immediately returns

    However, I guess that we need flush_events or some blocking functions to render images. Are these descriptions are simply outdated? Or, do I miss something?
    Any help is greatly appricated.

  3. richardsheridan commented on Apr 12, 2021

    @richardsheridan
    Contributor

    A little farther down in that page there are some exceptions to those bullet points:

    The GUI event loop being integrated with your command prompt and the figures being in interactive mode are independent of each other. If you use pyplot.ion but have not arranged for the event loop integration, your figures will appear but will not be interactive while the prompt is waiting for input.

    and

    Using figure.Figure.show it is possible to display a figure on the screen without starting the event loop and without being in interactive mode. This may work (depending on the GUI toolkit) but will likely result in a non-responsive figure.

    I think it is a subtle and possibly confusing point that interactive mode is not interactive unless you are working in a command prompt with event loop integration. That is, if you run a script with matplotlib code such as what you posted above, you will have a different result of interactivity compared with typing each command at the REPL.In my mind, the thing you need to do to get interactivity is pump GUI events, and plt.ion just configures some of the pyplot API to "work better" at the REPL.

    Perhaps bringing these facts forward in doc/users/interactive.rst before the bullet points would help?

  4. QuLogic commented on Apr 13, 2021

    @QuLogic
    Member
            time.sleep(0.1)

    You should replace this with plt.pause(0.1) to run the main loop.

  5. added this to the v3.5.0 milestone on Apr 13, 2021
  6. kngwyu commented on Apr 13, 2021

    @kngwyu
    Author

    I think it is a subtle and possibly confusing point that interactive mode is not interactive unless you are working in a command prompt with event loop integration.

    Right, I didn't actually understand that point.

    Perhaps bringing these facts forward in doc/users/interactive.rst before the bullet points would help?

    Thank you for the pointer. I would like also to mention that some backends behaved inconsistently on this point, but they are fixed.

  7. modified the milestones: v3.5.0, v3.6.0 on Sep 25, 2021
  8. removed their assignment
    on Jul 8, 2022
  9. modified the milestones: v3.6.0, v3.7.0 on Jul 8, 2022
  10. modified the milestones: v3.7.0, v3.7.1 on Feb 14, 2023
  11. modified the milestones: v3.7.1, v3.7-doc on Mar 4, 2023
  12. modified the milestones: v3.7-doc, v3.8-doc on Sep 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions