Repository navigation
Description
Bug report
In wxpython 4.1.0 initial support was added for high DPI awareness on Windows. Using matplotlib with the wxAgg backend and wxpython 4.1.0 on Windows results in everything being drawn at the wrong size. This is shown below, where the same plot is made without (left) and with (right) high DPI awareness turned on. For reference, I'm doing this on a 5120x2880 display with scale factor set to 200%.
Left, without high DPI awareness, right with high DPI awareness:

Code for reproduction
import ctypes
import wx
import matplotlib as mpl
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
class PlotFrame(wx.Frame):
def __init__(self, parent, title, *args, **kwargs):
wx.Frame.__init__(self, parent, title=title, *args, **kwargs)
self.fig = mpl.figure.Figure((5,4))
self.subplot1 = self.fig.add_subplot(111)
self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, self.fig)
self.toolbar = NavigationToolbar2WxAgg(self.canvas)
self.toolbar.Realize()
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
sizer.Add(self.toolbar, 0, wx.GROW)
self.subplot1.plot([0, 1, 2, 3, 4], [0, 2, 4, 9, 16], '-o')
self.SetSizer(sizer)
self.Layout()
self.Fit()
self.CenterOnScreen()
self.Show(True)
if __name__ == '__main__':
# Windows high DPI support
try:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
except:
pass
app = wx.App(False)
frame = PlotFrame(None, 'My Plot Frame')
app.MainLoop()Alternatively, using pyplot the issue is also reproduced:
import ctypes
import matplotlib as mpl
import matplotlib.pyplot as plt
# Windows high DPI support
try:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
except:
pass
mpl.use('wxAgg')
plt.plot(range(10), range(10)[::-1])
plt.show()Actual and expected outcomes
Actual outcome is a window that is half size, with all fonts, line thicknesses, icons, etc at half size (presumably because it's not accounting for the 200% scale factor). The expected outcome is something identical to the plot with high DPI awareness turned off, except sharp (i.e. natively rendering fonts, lines, etc at 2x size, instead of rendering at 1x and then Windows doing the scaling).
This is shown in the image above, reproduced here:

Matplotlib version
- Operating system: Windows 10
- Matplotlib version: Latest from git, displays as 3.3.2+1628.gfa547835c
- Matplotlib backend (
print(matplotlib.get_backend())): WxAgg - Python version: 3.8.2
- Other libraries: Wxpython 4.1.0
- Additional info: Tested on a 5120x2880 display with scale factor set to 200%.
Python installed through conda, matplotlib installed from source, wxpython 4.1.0 installed via pip (4.1.0 not available on conda yet).
Activity
jbhopkins commentedon Nov 12, 2020
I believe that the solution is likely to lie in using the new
FromDIPmethod in 4.1.0 to scale all the pixel sizes sent to the renderer appropriately (this ought to also work for backends where high DPI scaling isn't explicitly needed, such as MacOS). In my own wxpython GUI I've added the function below to provide back compatibility with previous versions of wx.I looked through the backend code a bit, but I found the calls to the renderer confusing, and wasn't sure where this could be added. If someone wants to guide me, I'm happy to make and test the changes.
Also, the high res version of the toolbar icons should be loaded if needed.
tohc1 commentedon Feb 28, 2021
@jbhopkins I came across this while looking at a different issue in the wx backends and noticed in the code matplotlib/backend/backend_wx.py that the dpi is hard-coded.
I think just changing to the dpi as read from wx.GetDisplayPPI() will cause the scaling to change. A quick test on Linux suggests that this function detects a dpi scaling change when changing the user interface scaling from x1 dpi=96 to x2 dpi=192.
jbhopkins commentedon Mar 1, 2021
@tohc1 Thanks! I'll test that out when I have the chance. If that does it, then the only other thing that has to be done is load in the high DPI icons when appropriate.
github-actions commentedon Sep 13, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
QuLogic commentedon Sep 13, 2023
#26710 should fix this.