Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add a backend kwarg to savefig.#15536

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
NelleV merged 1 commit intomatplotlib:masterfromanntzer:backendsavefigkwarg
Oct 30, 2019

Conversation

anntzer
Copy link
Contributor

This makes it easier e.g. to test the pgf backend without globally
switching the backend.

Makes it easier to work on pgf related issues; also helps with#13994 (attn@ArchangeGabriel; see changelog).

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code isFlake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

ArchangeGabriel reacted with thumbs up emojiArchangeGabriel reacted with hooray emojiArchangeGabriel reacted with heart emoji
@tacaswelltacaswell added this to thev3.3.0 milestoneOct 27, 2019
@tacaswell
Copy link
Member

Notionally 👍 one slight behavior question.

Adding a the new parameter which is sometimes Nonefirst is a bit odd to me, but I see the argument for that as it is consulted first.

@anntzer
Copy link
ContributorAuthor

backend has priority over fmt, so that's why I put them in this order (also, it's private API anyways).

@timhoffm
Copy link
Member

timhoffm commentedOct 27, 2019
edited
Loading

I'm a bit hesitant. A backend parameter insavefig() is a big API promise. I really don't claim to understand the whole backend machinery, but, setting the backend only for thesavefig() call feels too easy given that we've been jumping a lot of hoops to delay backend selection. Is this really a fully working solution that can live up to the API promised?

  • Does nothing we do in any plotting command (now or in the future) depend on the backend? Otherwise just setting the backend insavefig() is not equivalent to setting the backend earlier, and that would be quite surprising.
  • Following a similar logic, can we then equally doplt.show(backend='QtAgg')?
  • Would a context manager for backends be a reasonable alternative.
  • Do we need checks that the format/extension and the backend are compatible?

else:
# Return a default canvas for the requested format, if it exists.
canvas_class = get_registered_canvas_class(fmt)
if not hasattr(canvas_class, f"print_{fmt}"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think this is in the wrong block of the if/elif/else.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

oops, fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That probably means that a unit test should be written for this :)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

fair enough, done

@anntzer
Copy link
ContributorAuthor

re@timhoffm:

Does nothing we do in any plotting command (now or in the future) depend on the backend? Otherwise just setting the backend in savefig() is not equivalent to setting the backend earlier, and that would be quite surprising.

Ibelieve not (the backend-dependent logic is in draw(), which is only called by savefig()).

Following a similar logic, can we then equally do plt.show(backend='QtAgg')?

Backend switching is subject to the same rules as use() (i.e. you cannot switch to an interactive backend requiring a GUI event loop once another GUI event loop is running). But switching to a noninteractive backend is fine (and the intended use case) -- note that wealready implicitly do so for printing to pdf/ps/svg; this kwarg only makes it explicit and allows you to switch to backend_pgf rather than backend_pdf when printing to pdf.

Would a context manager for backends be a reasonable alternative.

I don't think there is anything else one would want to do within the context manager other than doing the save, which suggests that factoring out the backend switching is not worth it.

Do we need checks that the format/extension and the backend are compatible?

This has been added per@tacaswell's suggestion.

@timhoffm
Copy link
Member

@anntzer thanks for the clarification.

I believe not (the backend-dependent logic is in draw(), which is only called by savefig()).

Are use cases affected that use an intermediate draw to get some position information and use that to position subsequent elements?

Backend switching is subject to the same rules as use() (i.e. you cannot switch to an interactive backend requiring a GUI event loop once another GUI event loop is running). But switching to a noninteractive backend is fine (and the intended use case)

Something like this should be explicitly mentioned in the docstring of the backend parameter; maybe even with a list of supported builtin backends.

The other points are ok.

@anntzer
Copy link
ContributorAuthor

Are use cases affected that use an intermediate draw to get some position information and use that to position subsequent elements?

You'd run into the same issues (if any) as if saving to pdf from an interactive canvas, so nothing new.

Something like this should be explicitly mentioned in the docstring of the backend parameter; maybe even with a list of supported builtin backends.

done.

@ArchangeGabriel
Copy link
Contributor

@anntzer Thanks for this work! Does the PR include asavefig.backend rcParams (it does not seems so), and if not could it be possible to add one?

@anntzer
Copy link
ContributorAuthor

It doesn't and fwiw I still don't like the idea.

ArchangeGabriel reacted with thumbs up emoji

backend : str, optional
When set, forcibly use this non-interactive backend for rendering.
This can be either a standard backend name ("agg", "pdf", "pgf",
"ps", "svg") or a custom backend name ("module://...").
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This could use a comment as to why we would ever want to do this. I'm not sure I understand from the PR what the goal is, so I can imagine users trying to dutifully use this keyword and getting themselves into a mess.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

done

"ps", "svg") or a custom backend name ("module://..."). The main
use case of this parameter is to render to a format using a backend
that is neither the current backend, nor the default backend for
this format, e.g. for rendering pdfs using the pgf backend.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm still not clear. Are there other examples, like cairo instead of agg etc? If there is just one use case, I don't think this should get such a generic sounding kwarg name. If there are other cases, I'm confused about which ones are allowed. If I save to png, can I use pgf? Can I use the pdf backend to save to svg? Where are the compatibilities documented?

Copy link
ContributorAuthor

@anntzeranntzerOct 28, 2019
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Indeed, you can also use cairo (either the builtin, so "cairo", or mplcairo ("module://mplcairo.base")) to save to any format.
For the builtin backends the compat table is athttps://matplotlib.org/devdocs/tutorials/introductory/usage.html#the-builtin-backends (except that pgf is missing -- will open a separate PR for that -- now at#15555).

Copy link
Member

@jklymakjklymakOct 28, 2019
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

OK, thats more clear. I wonder if we change the kwarg torenderer and refer to this table somehow?

renderer: str, optional     Use a non-default backend to render the file, i.e. `renderer='cairo'` for a png rather than the default 'agg' backend, or 'pgf' for a PDF instead of the default 'pdf'.  See :doc:`/tutorials/introductory/usage` for a list of valid backends for each file format.  Note custom backends can be referenced as "module://...".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

BTW just to be clear, I'm balking at "backend" because the user will already have likely been subjected to the confusing idea that they have to select a backend, and then see this kwarg and assume the have to make it match up somehow. I think we should try and be clear that 99.9% of the time the user should not need to use this kwarg.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The doc sounds good, mostly used your suggestion with minor edits.
The argument matches the argument tomatplotlib.use(), so I think it makes sense to keep the same argument name, so I'd still preferbackend here.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

and added "Note that the default backend is normally sufficient."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sounds good (though you didn't push anything yet, right?)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

oops, missed the push, done now

@tacaswell
Copy link
Member

Doc failures look real:

/home/circleci/project/lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.savefig:98: WARNING: Unknown target name: "the-builtin-backends"./home/circleci/project/lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.savefig:98: WARNING: Unknown target name: "the-builtin-backends"./home/circleci/project/lib/matplotlib/backend_bases.py:docstring of matplotlib.backend_bases.FigureCanvasBase.print_figure:42: WARNING: Unknown target name: "the-builtin-backends".

Copy link
Member

@tacaswelltacaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

👍 modulo fixing the doc build

This makes it easier e.g. to test the pgf backend without globallyswitching the backend.
@anntzer
Copy link
ContributorAuthor

doc build fixed

@NelleVNelleV merged commit3272f8c intomatplotlib:masterOct 30, 2019
@anntzeranntzer deleted the backendsavefigkwarg branchOctober 30, 2019 10:17
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@NelleVNelleVNelleV left review comments

@tacaswelltacaswelltacaswell approved these changes

@jklymakjklymakjklymak approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v3.3.0
Development

Successfully merging this pull request may close these issues.

6 participants
@anntzer@tacaswell@timhoffm@ArchangeGabriel@NelleV@jklymak

[8]ページ先頭

©2009-2025 Movatter.jp