Skip to content

Request: for non-interactive backends make fig.canvas.draw() force the render #16558

Closed

Description

@pharshalp

Bug report

Bug summary
https://discourse.matplotlib.org/t/fig-draw-renderer-vs-fig-canvas-draw/20890

When using a non-interactive backend (specifically the PGF backend), I noticed that fig.canvas.draw() isn’t equivalent to fig.draw(fig.canvas.get_renderer()). Can anyone please explain the difference between these two approaches?

(this has been answered) Please see the explanation by @tacaswell on discourse.

Reproducing the last part of the response since it is potentially an actionable item

I suspect that we should add code to the draw methods of the non-interactive backends to force the render, but that needs a bit of thought to make sure we don’t have any unintended consequences of that.

Activity

  1. changed the title [-]Feature request: for non-interactive backends make fig.canvas.draw() force the render[/-] [+]Request: for non-interactive backends make fig.canvas.draw() force the render[/+] on Feb 19, 2020
  2. added this to the v3.3.0 milestone on Feb 20, 2020
  3. tacaswell commented on Feb 20, 2020

    @tacaswell
    Member

    I assume the use-case here is to then adjust things where you need to know what ticks are picked, text sizes, ect?

  4. pharshalp commented on Feb 20, 2020

    @pharshalp
    ContributorAuthor
  5. pharshalp commented on Feb 20, 2020

    @pharshalp
    ContributorAuthor

    Please ignore my earlier response ... I was half asleep when I responded via email :D

    Here is a stripped-down (maybe not so stripped-down?) version of my use-case

    import numpy as np
    import matplotlib.pyplot as plt
    
    plt.switch_backend('pgf')  # Switching to the PGF backend
    fig, ax = plt.subplots(figsize=(6, 3.0), ncols=2, nrows=1,
                           constrained_layout=True, sharey=True)
    fig.set_constrained_layout_pads(wspace=0.03)
    
    ax[0].plot(np.arange(4), 'r', label=r'Really longgggg label 1')
    ax[1].plot(np.arange(5), 'b', label=r'Really longgggg label 2')
    (leg_h0, leg_lab0) = ax[0].get_legend_handles_labels()
    (leg_h1, leg_lab1) = ax[1].get_legend_handles_labels()
    
    # add a legend to one of the axes to make space at the top of the figure
    leg0 = ax[0].legend(leg_h0, leg_lab0, loc='lower center',
                        bbox_to_anchor=(0.5, 1.07))
    
    leg0.set_in_layout(True)  # force to steal space from top of the figure
    # ------------------------------------------------------
    # Trigger a draw (required for constrained_layout to work)
    # fig.canvas.draw()   # Doesn't work!
    fig.draw(fig.canvas.get_renderer())  # works!
    # ------------------------------------------------------
    # Thanks constrained_layout, your work is done! turning you off now
    fig.set_constrained_layout(False)
    
    # Remove legend from axes and add a figure legend
    # which includes entries from both axes
    leg0.remove() 
    fig_leg = fig.legend(*zip(leg_h0, leg_h1), *zip(leg_lab0, leg_lab1),
                         loc='lower center', ncol=2, columnspacing=5,
                         bbox_to_anchor=(0.5, 0.85))
    fig.savefig('test.png', dpi=200)

    test

  6. tacaswell commented on Feb 20, 2020

    @tacaswell
    Member

    Would you want to take a crack at implementing this?

    I think the upside (that fig.canvas.draw always does the same thing) outweighs the downside (the biggest risk I see is someone relying on draw and draw_idle being no-ops when run with a non-interactive backend but wanting them there on an alternate interactive usage).

  7. pharshalp commented on Feb 20, 2020

    @pharshalp
    ContributorAuthor
  8. tacaswell commented on Feb 20, 2020

    @tacaswell
    Member

    Having an implementation would be good to move the conversation along. I don't think this will be a tremendous amount of work and having a concrete implementation will make it easier to think about.

  9. modified the milestones: v3.3.0, v3.4.0 on May 7, 2020
  10. pharshalp commented on Feb 17, 2021

    @pharshalp
    ContributorAuthor

    closed by #18408

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions