Skip to content

Commit

Permalink
Merge pull request #1236 from astrofrog/fix-matplotlib-retina
Browse files Browse the repository at this point in the history
Fix selections when using Matplotlib 2.x, PyQt5 and a retina display
  • Loading branch information
astrofrog committed Feb 10, 2017
2 parents 6db4e56 + 2205bf2 commit 41659f5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -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. [#1236]

- 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]
Expand Down
35 changes: 34 additions & 1 deletion glue/core/qt/roi.py
Expand Up @@ -3,7 +3,8 @@
import numpy as np

from qtpy.QtCore import Qt
from qtpy import QtCore, QtGui, QtWidgets
from qtpy import QtCore, QtGui, PYQT5

from glue.core import roi
from glue.utils.qt import mpl_to_qt4_color

Expand Down Expand Up @@ -58,8 +59,23 @@ 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():
ratio = self.canvas.devicePixelRatio()
pts /= ratio

pts[:, 1] = self.canvas.height() - pts[:, 1]
return pts[:, 0], pts[:, 1]

Expand Down Expand Up @@ -145,8 +161,25 @@ 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():
ratio = self.canvas.devicePixelRatio()
xy[0] /= ratio
xy[1] /= ratio
radius /= ratio

center = QtCore.QPoint(xy[0], canvas.height() - xy[1])

p = self.get_painter(canvas)
Expand Down

0 comments on commit 41659f5

Please sign in to comment.