Skip to content

IPython is always imported by pyplot, if present #5037

Closed

Description

@efiring

When IPython is present, the import time for pyplot is roughly doubled because IPython is imported by install_repl_displayhook(). This is true even with matplotlib.use('agg'), so it will affect all scripts using pyplot.

Activity

  1. added
    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
    on Sep 9, 2015
  2. added this to the milestone on Sep 9, 2015
  3. added a commit that references this issue on Sep 9, 2015
    bc20fe2
  4. self-assigned this
    on Sep 9, 2015
  5. OceanWolf commented on Sep 9, 2015

    @OceanWolf
    Member

    Hmm, going back to what I said in the line comments of #4506, lets control this auto-redraw based on a simple rcParam check rather than using iPython...

  6. tacaswell commented on Sep 9, 2015

    @tacaswell
    Member

    There are two ways to deal with clearing the stale state. Either when the figure comes stale it can tell the canvas to schedule a re-draw at it's next opportunity (which is what happens currently if you are not in IPython) and the other is that some external loop comes around and asks the figures if they are stale, and if so, triggers the canvas to re-draw.

    I very much prefer option 2 as it puts control of the draw cadence in the hands of the event loop that is running the show, instead of mpl constantly poking at the canvas. It prevents any possibility of the nasty infinite draw-triggering-draw loops that we had to deal with (but I think those are all sorted out for the backends we ship).

    The plain python repl does not have a convenient place to hook a callback function into, hence in that case we have to use the push pattern.

    I don't see how in either case an rcparam helps deal with when to trigger asynchronous draws.

  7. efiring commented on Sep 9, 2015

    @efiring
    MemberAuthor

    It's greatly improved, but I'm still seeing a considerable increase in import time from 1.4.3 to master, with #5038 included. The number of function calls has gone from 179,087 to 252,421, and the time is still about 100 ms longer (280 to 380) on my Linux VM. The increase is split between the matplotlib.__init__ and the pyplot, with a somewhat larger fractional contribution from the latter. (This is based on stats from a single run with kernprof.) Has our LOC count increased by this much? About 40%? I wouldn't think so.

  8. tacaswell commented on Sep 9, 2015

    @tacaswell
    Member

    according to git we are net +22k LoC, but a lot of that is probably svgs

    22:41 $ git diff v1.4.3 --shortstat
     2617 files changed, 243561 insertions(+), 220919 deletions(-)
    
  9. mdehoon commented on Sep 9, 2015

    @mdehoon
    Contributor

    There are two ways to deal with clearing the stale state. Either when the figure comes stale it can tell the canvas to schedule a re-draw at its next opportunity (which is what happens currently if you are not in IPython) and the other is that some external loop comes around and asks the figures if they are stale, and if so, triggers the canvas to re-draw.

    Option 1 is the traditional way of organizing event loops on Windows, Mac, X11. I would suggest to consider carefully why matplotlib would need an approach different from other GUI programs.

    The plain python repl does not have a convenient place to hook a callback function into, hence in that case we have to use the push pattern.

    I believe you were looking for a function that is called when Python is waiting for the next command?
    If so, then at least with tkagg you could use Tkinter's after_idle.

  10. OceanWolf commented on Sep 9, 2015

    @OceanWolf
    Member

    Yes, I thought we had draw_idle to do exactly that. It works like a mailbox flag. When you change some properties that means we need the artist redrawn, we raise the flag to say "come here", and notify the system that it needs to make a round when it has free time. Based on previous comments regarding embedding, I think we would want to use an rcParam to control whether the artist will raising of the flag will automatically request a draw_idle. As with the mail, If the draw_idle execution has not yet begun, another request for it will just represent a no-op.

    Anyway, not a biggie, I think we can change to this or some other behaviour safely enough at a later point... but I thought if we needed to get rid of that IPython import now, then we can/should do it this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions