Feedback request for matplotib wxPython users

If you use matplotlib and wxPython together on MSW then I would kindly request your feedback.

A question has arisen during the discussion of a matplotlib pull request to upgrade the wxPython backend to add support for high DPI displays.

The question is whether end-user code or matplotlib should notify MSW of the level of DPI support desired. The question only applies when using wxPython and matplotlib together on MSW. More details are in the full discussion: Add support for High DPI displays to wxAgg backend by jmoraleda · Pull Request #26710 · matplotlib/matplotlib · GitHub

This impacts users that embed matplotlib figures in their wxPython applications by using controls derived from matplotlib.backends.backend_wxagg.FigureCanvasWxAgg as well as users that explicitly set wxAgg as backend in matplotlib.

It would be nice to take in the input of other users of this functionality. So if you would like to share your thoughts, please feel free to add them to the discussion in github. Thank you.

As the author of applications for others to use that make heavy use of wxPython and matplotlib, using (and supporting) the wxmplot library for that combination, I might have comments. But I sort of don’t know what the question is. What is the question?

A quick look at the discussion in the matplotlib PR leaves me more confused. The initial PR says right there in the title that the PR is for wxAgg. It also says it closes matplotlib #7720, which is explicitly only relevant to MacOS. The message here explicitly states that it is relevant for Windows. What platforms are you actually talking about?

As an application author, how would I know what the DPI setting was for a system (or individual monitor) that a user chooses to use? Wouldn’t that be necessary in order to set this on behalf of the user of my application? For sure, application users will most likely not even know that they are using matplotlib, wxPython, or maybe even Python. If DPI resolution can be determined programmatically, I completely and utterly disagree with the statements made in the PR that this should be something the user sets. I think the application library (ie, the matplotlib wx or wxagg backend) should try to detect and set this accordingly on behalf of the user.

Sorry if this sounds pessimistic, but I do not understand the logic of the PR well enough to agree or disagree with it.

Hello @Matthew_Newville Thank you for taking the time to read through the PR and replying.

Background

For understanding current wx support for building applications that display sharply in high resolution displays you may read: wxWidgets: High DPI Support in wxWidgets There you will find a reference to platform specific issues. In particular in the section for MSW you will be pointed to this document: High DPI Desktop Application Development on Windows - Win32 apps | Microsoft Learn.

This MS documentation above explains that what level of high resolution display support an application gets on MSW is specified by the application itself. In particular it specifies whether the O/S should scale up images and fonts, etc. by zooming, thus blurring them, or whether the application code will do it by drawing them with more pixels, by thus keeping them sharp. If scaling is not done, the images appear sharp, but very small because the pixels in high resolution displays are smaller than “regular” so anything using the same number of pixels as in lower resolution displays will appear small and not easy to see.

When a wx application displays on a high resolution display, it is the responsibility of the application developer that all custom (non-wx rendered) widget is drawn taking into account the display resolution. For legacy applications that don’t do this. It is best to let the O/S do the scaling for all the widgets, at the expense of some blur. Else some windows will be scaled and some others won’t, which will change the relative sizes of widows with respect to the intended layout and the UI will be very bad looking.

The previous two paragraphs are not relevant to non-MSW platforms as in those the O/S performs scaling per widget not per application.

What this PR does

The PR refenerenced enhances the matplotlib wx backend so that matplotlib figures drawn using the wx backend display sharply in high resolution monitors and at the expected physical size. The PR adds support for this behavior in Windows, Mac and GTK. Without this PR matplotlib figures drawn using the wx backend on high resolution displays will look either too small or the right size but blurry.

What my original question was

The original question was whether matplotlib or end user code should tell the O/S whether for the whole application, user code would do the scaling or whether the O/S should do the scaling. As discussed above this is only done in MSW since the scaling setting on MAC and GTK is per widget.

If all custom widgets are matplotlib figures (which is the case when using wxAgg rather than embedding figures in a wx application) then, with this PR, they will all have support for displaying sharply and at the correct size, and matplotlib could tell the O/S that end user code will do the scaling. But when embedding matplotlib figures in an application, the user needs to update their custom widgets before telling this to the O/S. So it should be user code that notifies the O/S of the desired dpi support.

We have figured out a way to distinguish the two cases, so the question has already been answered (Add support for High DPI displays to wxAgg backend by jmoraleda · Pull Request #26710 · matplotlib/matplotlib · GitHub)

Even though the question has already been answered, I figured that this longer explanation might provide a service to the community.

Looking at the PR, the only change to the wxagg backend appears to be to always scale the rendered bitmap by the DPI scale factor. That seems fine to me. I don’t see that this requires user intervention.

But you still say here that:
"If all custom widgets are matplotlib figures (which is the case when using wxAgg rather than embedding figures in a wx application) then, with this PR, they will all have support for displaying sharply and at the correct size, and matplotlib could tell the O/S that end user code will do the scaling. But when embedding matplotlib figures in an application, the user needs to update their custom widgets before telling this to the O/S. So it should be user code that notifies the O/S of the desired dpi support.

I read that as saying the two cases are
A) “custom widgets are matplotlib figures”
B) “when embedding matplotlib figures in an application”

How are those two cases different? Is the difference here based on which matplotlib backend is used?
Like for case A) do you mean “using backend_wx, but not backend_wxagg”? Is case B) “rendered a png or svg with matplotib and then show that image as a bitmap”?

Your original message said:
“This impacts users that embed matplotlib figures in their wxPython applications by using controls derived from matplotlib.backends.backend_wxagg.FigureCanvasWxAgg as well as users that explicitly set wxAgg as backend in matplotlib.”

So I am still confused by what you are saying and what sort of response you might be looking for.