Skip to content

Commit

Permalink
Merge ab48532 into 8bbfa14
Browse files Browse the repository at this point in the history
  • Loading branch information
astrofrog committed Oct 29, 2017
2 parents 8bbfa14 + ab48532 commit f5f78cc
Show file tree
Hide file tree
Showing 21 changed files with 127 additions and 16 deletions.
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ env:
global:
# Pin freetype to 2.5.5 to keep image tests consistent
- CONDA_DEPENDENCIES="numpy matplotlib freetype=2.5.5 mock"
- PIP_DEPENDENCIES="pytest-mpl fast-histogram"
- PIP_DEPENDENCIES="pytest-mpl fast-histogram coveralls pytest-cov"
- SETUP_XVFB=true
matrix:
- PYTHON_VERSION=2.7
Expand All @@ -24,4 +24,7 @@ install:

script:
- python setup.py check --restructuredtext
- pytest mpl_scatter_density --mpl -p no:warnings
- pytest mpl_scatter_density --mpl -p no:warnings --cov mpl_scatter_density

after_success:
- coveralls
19 changes: 9 additions & 10 deletions mpl_scatter_density/scatter_density_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,20 @@ class ScatterDensityArtist(AxesImage):
"""

def __init__(self, ax, x, y, dpi=72, downres_factor=4, color=None, c=None,
vmin=None, vmax=None, **kwargs):
vmin=None, vmax=None, norm=None, **kwargs):

super(ScatterDensityArtist, self).__init__(ax, **kwargs)

self._c = None
self._downres = False
self._density_vmin = np.nanmin
self._density_vmax = np.nanmax

self._ax = ax
self._ax.figure.canvas.mpl_connect('button_press_event', self.downres)
self._ax.figure.canvas.mpl_connect('button_release_event', self.upres)

if downres_factor < 1:
if downres_factor < 1 or downres_factor % 1 != 0:
raise ValueError('downres_factor should be a strictly positive integer value')

self._downres_factor = downres_factor
Expand All @@ -90,6 +91,9 @@ def __init__(self, ax, x, y, dpi=72, downres_factor=4, color=None, c=None,
if color is not None:
self.set_color(color)

if norm is not None:
self.set_norm(norm)

if vmin is not None or vmax is not None:
self.set_clim(vmin, vmax)

Expand Down Expand Up @@ -136,7 +140,7 @@ def downres(self, event=None):
return
try:
mode = self._ax.figure.canvas.toolbar.mode
except AttributeError:
except AttributeError: # pragma: nocover
return
if mode != 'pan/zoom':
return
Expand All @@ -154,11 +158,6 @@ def get_extent(self):
ymin, ymax = self.axes.get_ylim()
return xmin, xmax, ymin, ymax

def get_window_extent(self, renderer=None):
x0, x1, y0, y1 = self.get_extent()
bbox = Bbox.from_extents([x0, y0, x1, y1])
return bbox.transformed(self.axes.transData)

def get_transform(self):

# If we don't override this, the transform includes LogTransforms
Expand Down Expand Up @@ -223,7 +222,7 @@ def make_image(self, *args, **kwargs):
x = self._x_sub
else:
x = self._x
else:
else: # pragma: nocover
raise ValueError('Unexpected xscale: {0}'.format(xscale))

if yscale == 'log':
Expand All @@ -241,7 +240,7 @@ def make_image(self, *args, **kwargs):
y = self._y_sub
else:
y = self._y
else:
else: # pragma: nocover
raise ValueError('Unexpected xscale: {0}'.format(xscale))

if self._downres:
Expand Down
6 changes: 3 additions & 3 deletions mpl_scatter_density/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

baseline_root = 'baseline'

if MPL_VERSION >= LooseVersion('2'):
if MPL_VERSION >= LooseVersion('2'): # pragma: nocover
baseline_subdir = '2.0.x'
elif MPL_VERSION >= LooseVersion('1.5'):
elif MPL_VERSION >= LooseVersion('1.5'): # pragma: nocover
baseline_subdir = '1.5.x'
else:
else: # pragma: nocover
raise ValueError('Matplotlib {0} is not supported'.format(matplotlib.__version__))

baseline_dir = os.path.join(baseline_root, baseline_subdir)
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
111 changes: 110 additions & 1 deletion mpl_scatter_density/tests/test_scatter_density_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
import numpy as np
import matplotlib.pyplot as plt

try:
import astropy # noqa
except ImportError: # pragma: nocover
ASTROPY_INSTALLED = False
else:
ASTROPY_INSTALLED = True

from ..scatter_density_artist import ScatterDensityArtist

from . import baseline_dir
Expand Down Expand Up @@ -77,12 +84,18 @@ def test_multi_scatter(self):
return self.fig

@pytest.mark.mpl_image_compare(style={}, baseline_dir=baseline_dir)
def test_downres(self):
@pytest.mark.parametrize('log', [True, False])
def test_downres(self, log):
a = ScatterDensityArtist(self.ax, self.x1, self.y1, downres_factor=10)
self.ax.add_artist(a)
self.ax.figure.canvas.toolbar = MagicMock()
self.ax.figure.canvas.toolbar.mode = 'pan/zoom'
a.downres()
self.ax.set_xlim(0.1, 3.)
self.ax.set_ylim(0.1, 3.)
if log:
self.ax.set_xscale('log')
self.ax.set_yscale('log')
return self.fig

def test_no_dpi(self):
Expand Down Expand Up @@ -123,3 +136,99 @@ def test_colorcode_downres(self):
self.ax.figure.canvas.toolbar.mode = 'pan/zoom'
a.downres()
return self.fig

@pytest.mark.mpl_image_compare(style={}, baseline_dir=baseline_dir)
@pytest.mark.parametrize(('flipx', 'flipy'), [(False, False), (False, True),
(True, False), (True, True)])
def test_flipping(self, flipx, flipy):
a = ScatterDensityArtist(self.ax, self.x1, self.y1)
self.ax.add_artist(a)
if flipx:
self.ax.set_xlim(5, -3)
else:
self.ax.set_xlim(-3, 5)
if flipy:
self.ax.set_ylim(6, -2)
else:
self.ax.set_ylim(-2, 6)
return self.fig

@pytest.mark.skipif('not ASTROPY_INSTALLED')
@pytest.mark.mpl_image_compare(style={}, baseline_dir=baseline_dir)
def test_norm(self):

from astropy.visualization import LogStretch
from astropy.visualization.mpl_normalize import ImageNormalize

norm = ImageNormalize(vmin=0., vmax=1000, stretch=LogStretch())

a = ScatterDensityArtist(self.ax, self.x1, self.y1, norm=norm)
self.ax.add_artist(a)
self.ax.set_xlim(-3, 5)
self.ax.set_ylim(-2, 4)

return self.fig

@pytest.mark.mpl_image_compare(style={}, baseline_dir=baseline_dir)
def test_manual_limits(self):

a = ScatterDensityArtist(self.ax, self.x1, self.y1, vmin=-100, vmax=300)
self.ax.add_artist(a)
self.ax.set_xlim(-3, 5)
self.ax.set_ylim(-2, 4)

return self.fig

@pytest.mark.parametrize('value', [-3, 0, 3.2])
def test_invalid_downsample(self, value):

with pytest.raises(ValueError) as exc:
ScatterDensityArtist(self.ax, self.x1, self.y1, downres_factor=value)
assert exc.value.args[0] == 'downres_factor should be a strictly positive integer value'

def test_downres_ignore_unity(self):

# Make sure that when using a downres_factor of 1, we
# are efficient and don't mark image as stale (which
# would force a re-computation/draw)

a = ScatterDensityArtist(self.ax, self.x1, self.y1, downres_factor=10)
self.ax.add_artist(a)
self.ax.figure.canvas.toolbar = MagicMock()
self.ax.figure.canvas.toolbar.mode = 'pan/zoom'
self.ax.figure.canvas.draw()
assert not a.stale
a.downres()
assert a.stale

a = ScatterDensityArtist(self.ax, self.x1, self.y1, downres_factor=1)
self.ax.add_artist(a)
self.ax.figure.canvas.toolbar = MagicMock()
self.ax.figure.canvas.toolbar.mode = 'pan/zoom'
self.ax.figure.canvas.draw()
assert not a.stale
a.downres()
assert not a.stale

def test_default_dpi(self):

self.fig.set_dpi(90)
a = ScatterDensityArtist(self.ax, self.x1, self.y1, dpi=None)
self.ax.add_artist(a)
self.ax.figure.canvas.draw()
assert a.get_size() == (216, 216)

def test_downres_ignore_other_tools(self):

# Make sure we ignore the downres if a tool other than pan/zoom is
# selected (since the user may then be clicking on the canvas for
# another reason)

a = ScatterDensityArtist(self.ax, self.x1, self.y1)
self.ax.add_artist(a)
self.ax.figure.canvas.toolbar = MagicMock()
self.ax.figure.canvas.toolbar.mode = 'apple picking'
self.ax.figure.canvas.draw()
assert not a.stale
a.downres()
assert not a.stale

0 comments on commit f5f78cc

Please sign in to comment.