From 7f947a3329cf75392d9644427e000376bea25b27 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Fri, 10 Feb 2017 15:10:43 +0000 Subject: [PATCH 1/3] Fix selections when using Matplotlib 2.x, PyQt5 and a retina display --- CHANGES.md | 2 ++ glue/core/qt/roi.py | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5829658df..5fd412dd3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -40,6 +40,8 @@ v0.10.0 (unreleased) and can be used to define logical relations between different attributes in a GUI-independent way. +- Fix selections when using Matplotlib 2.x, PyQt5 and a retina display. + - Updated ComponentIDComboHelper to no longer store ``(cid, data)`` as the ``userData`` but instead just the ``cid`` (the data is now accessible via ``cid.parent``). [#1212] diff --git a/glue/core/qt/roi.py b/glue/core/qt/roi.py index a16b864f7..ae7204fac 100644 --- a/glue/core/qt/roi.py +++ b/glue/core/qt/roi.py @@ -3,7 +3,8 @@ import numpy as np from qtpy.QtCore import Qt -from qtpy import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets, PYQT5 + from glue.core import roi from glue.utils.qt import mpl_to_qt4_color @@ -58,8 +59,22 @@ def draw_polygon(self, canvas, x, y): def _transform(self, x, y): """ Convert points from MPL data coords to Qt Widget coords""" t = self._axes.transData + xy = np.column_stack((x, y)) pts = t.transform(xy) + + # Matplotlib 2.x with PyQt5 on a retina display has a bug which means + # that the coordinates returned by transData are twice as large as they + # should be. Since we don't know when/if this bug will be fixed, we + # check whether the coordinates of the top right corner are outside + # the canvas. + if PYQT5: + xmax = self._axes.get_xlim()[1] + ymax = self._axes.get_ylim()[1] + xd, yd = t.transform((xmax, ymax)) + if xd > self.canvas.width() or yd > self.canvas.height(): + pts /= 2 + pts[:, 1] = self.canvas.height() - pts[:, 1] return pts[:, 0], pts[:, 1] @@ -145,8 +160,24 @@ def __init__(self, axes): roi.MplCircularROI.__init__(self, axes) def paint(self, canvas): + xy = list(map(int, self._roi.get_center())) radius = int(self._roi.get_radius()) + + # Matplotlib 2.x with PyQt5 on a retina display has a bug which means + # that the coordinates returned by transData are twice as large as they + # should be. Since we don't know when/if this bug will be fixed, we + # check whether the coordinates of the top right corner are outside + # the canvas. + if PYQT5: + xmax = self._axes.get_xlim()[1] + ymax = self._axes.get_ylim()[1] + xd, yd = self._axes.transData.transform((xmax, ymax)) + if xd > self.canvas.width() or yd > self.canvas.height(): + xy[0] /= 2 + xy[1] /= 2 + radius /= 2 + center = QtCore.QPoint(xy[0], canvas.height() - xy[1]) p = self.get_painter(canvas) From b53670a45cdbca5268904aa6f5d592aca2095b6c Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Fri, 10 Feb 2017 15:15:11 +0000 Subject: [PATCH 2/3] Use proper DPI scaling instead of 2 --- glue/core/qt/roi.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/glue/core/qt/roi.py b/glue/core/qt/roi.py index ae7204fac..e3797a265 100644 --- a/glue/core/qt/roi.py +++ b/glue/core/qt/roi.py @@ -3,7 +3,7 @@ import numpy as np from qtpy.QtCore import Qt -from qtpy import QtCore, QtGui, QtWidgets, PYQT5 +from qtpy import QtCore, QtGui, PYQT5 from glue.core import roi from glue.utils.qt import mpl_to_qt4_color @@ -73,7 +73,8 @@ def _transform(self, x, y): ymax = self._axes.get_ylim()[1] xd, yd = t.transform((xmax, ymax)) if xd > self.canvas.width() or yd > self.canvas.height(): - pts /= 2 + ratio = self.canvas.devicePixelRatio() + pts /= ratio pts[:, 1] = self.canvas.height() - pts[:, 1] return pts[:, 0], pts[:, 1] @@ -174,9 +175,10 @@ def paint(self, canvas): ymax = self._axes.get_ylim()[1] xd, yd = self._axes.transData.transform((xmax, ymax)) if xd > self.canvas.width() or yd > self.canvas.height(): - xy[0] /= 2 - xy[1] /= 2 - radius /= 2 + ratio = self.canvas.devicePixelRatio() + xy[0] /= ratio + xy[1] /= ratio + radius /= ratio center = QtCore.QPoint(xy[0], canvas.height() - xy[1]) From 2205bf2bf3e477f9a8606891b5ccfc4d0424587a Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Fri, 10 Feb 2017 17:10:39 +0000 Subject: [PATCH 3/3] Add PR number to changelog [ci skip] --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5fd412dd3..2144f2515 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -40,7 +40,7 @@ v0.10.0 (unreleased) and can be used to define logical relations between different attributes in a GUI-independent way. -- Fix selections when using Matplotlib 2.x, PyQt5 and a retina display. +- Fix selections when using Matplotlib 2.x, PyQt5 and a retina display. [#1236] - Updated ComponentIDComboHelper to no longer store ``(cid, data)`` as the ``userData`` but instead just the ``cid`` (the data is now accessible via