From cfff335e13e354cc706edb0f5646d638f26c3929 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 7 Aug 2017 00:25:34 -0400 Subject: [PATCH 1/2] FIX: Qt5 account for dpiratio as early as possible Previously, the canvas size would get set to too small because - in the FigureCanvasQt.__init__ `get_width_height` is used to set the initial size of the canvas - `get_width_height` accounts for the dpiratio, but it has not been multiplied up yet so it reports half the size it should - this get propagated back down into the Figure object in the resize method - the dpi is then scaled up This fix - moves adding the `_original_dpi` attribute to the Figure as soon as possible in the base __init__ - calls `_update_dpi` before asking the figure how big it is Closes #8717 --- lib/matplotlib/backends/backend_qt5.py | 7 +++++++ lib/matplotlib/backends/backend_qt5agg.py | 11 ----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index ab8c255680c7..68e534aa8c58 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -182,8 +182,13 @@ class FigureCanvasQT(QtWidgets.QWidget, FigureCanvasBase): # QtCore.Qt.XButton2: None, } + def _update_figure_dpi(self): + dpi = self._dpi_ratio * self.figure._original_dpi + self.figure._set_dpi(dpi, forward=False) + def __init__(self, figure): _create_qApp() + figure._original_dpi = figure.dpi # NB: Using super for this call to avoid a TypeError: # __init__() takes exactly 2 arguments (1 given) on QWidget @@ -192,6 +197,8 @@ def __init__(self, figure): # http://pyqt.sourceforge.net/Docs/PyQt5/pyqt4_differences.html#cooperative-multi-inheritance super(FigureCanvasQT, self).__init__(figure=figure) self.figure = figure + self._update_figure_dpi() + self.setMouseTracking(True) w, h = self.get_width_height() self.resize(w, h) diff --git a/lib/matplotlib/backends/backend_qt5agg.py b/lib/matplotlib/backends/backend_qt5agg.py index b7a90a8f4d68..78d9fdada4f6 100644 --- a/lib/matplotlib/backends/backend_qt5agg.py +++ b/lib/matplotlib/backends/backend_qt5agg.py @@ -190,17 +190,6 @@ class FigureCanvasQTAgg(FigureCanvasQTAggBase, FigureCanvasQT): """ - def __init__(self, figure): - super(FigureCanvasQTAgg, self).__init__(figure=figure) - # We don't want to scale up the figure DPI more than once. - # Note, we don't handle a signal for changing DPI yet. - self.figure._original_dpi = self.figure.dpi - self._update_figure_dpi() - - def _update_figure_dpi(self): - dpi = self._dpi_ratio * self.figure._original_dpi - self.figure._set_dpi(dpi, forward=False) - @_BackendQT5.export class _BackendQT5Agg(_BackendQT5): From ce7c8df6084fc2fe10116453c0e88f1aac79199d Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 9 Aug 2017 22:47:23 -0400 Subject: [PATCH 2/2] TST: correct expected canvas sizes The values in the test were the buggy values. We expect a (5, 2) in figure at 120 dpi to be (600, 240) screen pixels. --- lib/matplotlib/tests/test_backend_qt5.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/tests/test_backend_qt5.py b/lib/matplotlib/tests/test_backend_qt5.py index dc47afecc719..3f4bab6fa4f1 100644 --- a/lib/matplotlib/tests/test_backend_qt5.py +++ b/lib/matplotlib/tests/test_backend_qt5.py @@ -125,6 +125,7 @@ def test_dpi_ratio_change(): size = qt_canvas.size() qt_canvas.manager.show() + qt_canvas.draw() qApp.processEvents() # The DPI and the renderer width/height change @@ -133,8 +134,8 @@ def test_dpi_ratio_change(): assert qt_canvas.renderer.height == 720 # The actual widget size and figure physical size don't change - assert size.width() == 200 - assert size.height() == 80 + assert size.width() == 600 + assert size.height() == 240 assert_equal(qt_canvas.get_width_height(), (600, 240)) assert_equal(fig.get_size_inches(), (5, 2)) @@ -151,7 +152,7 @@ def test_dpi_ratio_change(): assert qt_canvas.renderer.height == 480 # The actual widget size and figure physical size don't change - assert size.width() == 200 - assert size.height() == 80 + assert size.width() == 600 + assert size.height() == 240 assert_equal(qt_canvas.get_width_height(), (600, 240)) assert_equal(fig.get_size_inches(), (5, 2))