Skip to content

WXAgg backend not rendering nicely on retina #7720

Closed

Description

@LtMerlin

When embedding a matplotlib plot in a WX.Panel, the figure_canvas is not rendered nicely on a retina display. Increasing the dpi of the figure does not help (it only alters the figure size).

Matplotlib version: 2.0.0rc2 (installed with pip) (same behaviour as with 1.5.3)
Python version: 2.7.13 (installed with homebrew)
Platform: OSX (macOS Sierra)

Plotting using standard MacOSX backend (no embedding):

import matplotlib
matplotlib.use("MacOSX") #put here explicitly for reference

from numpy import arange, sin, pi
import matplotlib.pyplot as plt

figure = plt.figure()
axes = figure.add_subplot(111)
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
axes.plot(t, s)

plt.show()

screenshot_using_macosx_backend

Plotting using the WXAgg backend (embed inside WX.Panel):

from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

import wx

class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def draw(self):
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)

if __name__ == "__main__":
    app = wx.App()
    fr = wx.Frame(None, title='test')
    panel = CanvasPanel(fr)
    panel.draw()
    fr.Show()
    app.MainLoop()

screenshot_wx_embed

Any workarounds or tips?

Activity

  1. tacaswell commented on Jan 1, 2017

    @tacaswell
    Member

    We are constrained by the underlying GUI toolkit's (WX's) support for retnia. Under the hood the way this works is mpl using Agg to render your plot as an RGB array with is then painted onto the screen via WX. Any mouse/keyboard events are captured by the GUI toolkit and passed back down into mpl to run the user interaction.

    What apple does by default is to scale all applications by drawing each pixel in the underlying application as a 2x2 grid on your screen. This is a reasonable choice (or all of your applications are suddenly half the size they used to be and text may become unreadable) but is very inconvenient for mpl.

  2. added this to the milestone on Jan 1, 2017
  3. tacaswell commented on Sep 24, 2017

    @tacaswell
    Member

    Closing as there is nothing we can do until WX provides the GUI level tooling to handle high-dpi screens.

  4. removed this from the milestone on Sep 24, 2017
  5. tianzhuqiao commented on Apr 5, 2023

    @tianzhuqiao

    Looks like now wxpython (4.2.0) handles the high-dpi screen much better. Do we have any plan to improve this? Thanks!

    https://docs.wxpython.org/wx.Bitmap.html#wx.Bitmap.GetScaleFactor
    https://docs.wxpython.org/wx.Window.html#wx.Window.GetDPIScaleFactor

  6. QuLogic commented on Apr 26, 2023

    @QuLogic
    Member

    There were not any specific plans since we aren't always watching wxPython changes, but we can re-open this issue based on this new information.

  7. greglucas commented on Apr 16, 2024

    @greglucas
    Contributor

    I just tested out the example and it appears to work now after #26710, so I think that should have closed this issue.

  8. added this to the v3.9.0 milestone on Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions