Skip to content

Commit

Permalink
Use an event-based approach to keeping axes margins fixed to make sur…
Browse files Browse the repository at this point in the history
…e AxesCache works
  • Loading branch information
astrofrog committed Sep 10, 2015
1 parent 2a252de commit f9546ca
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 45 deletions.
8 changes: 3 additions & 5 deletions glue/clients/histogram_client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import absolute_import, division, print_function

import numpy as np
import matplotlib.pyplot as plt

from ..core.client import Client
from ..core import message as msg
Expand All @@ -13,7 +12,7 @@
from .util import update_ticks, visible_limits
from ..core.callback_property import CallbackProperty, add_callback
from ..utils import lookup_class
from ..utils.matplotlib import fixed_margin_axes
from ..utils.matplotlib import fix_margins


class UpdateProperty(CallbackProperty):
Expand Down Expand Up @@ -59,9 +58,8 @@ def __init__(self, data, figure, artist_container=None):
super(HistogramClient, self).__init__(data)

self._artists = artist_container or LayerArtistContainer()
FixedMarginAxes = fixed_margin_axes(plt.Axes, [1, 0.5, 0.75, 0.5])
self._axes = FixedMarginAxes(figure)
figure.add_axes(self._axes)
self._axes = figure.add_subplot(111)
fix_margins(self._axes, [1, 0.25, 0.50, 0.25])
self._component = None
self._saved_nbins = None
self._xlim = {}
Expand Down
17 changes: 8 additions & 9 deletions glue/clients/viz_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import matplotlib.pyplot as plt
from ..core.client import Client
from ..core import Data
from ..utils.matplotlib import fixed_margin_axes
from ..utils.matplotlib import fix_margins
from .layer_artist import LayerArtistContainer

__all__ = ['VizClient', 'GenericMplClient']
Expand Down Expand Up @@ -143,26 +143,25 @@ def init_mpl(figure, axes, wcs=False, axes_factory=None):
raise ValueError("Axes and figure are incompatible")

try:
from ..external.wcsaxes import WCSAxes
from ..external.wcsaxes import WCSAxesSubplot
except ImportError:
WCSAxes = None
WCSAxesSubplot = None

if axes is not None:
_axes = axes
_figure = axes.figure
else:
_figure = figure or plt.figure()
if wcs and WCSAxes is not None:
FixedMarginWCSAxes = fixed_margin_axes(WCSAxes, [1, 0.5, 0.75, 0.5])
_axes = FixedMarginWCSAxes(_figure)
if wcs and WCSAxesSubplot is not None:
_axes = WCSAxesSubplot(_figure, 111)
_figure.add_axes(_axes)
fix_margins(_axes, [1, 0.25, 0.50, 0.25])
else:
if axes_factory is not None:
_axes = axes_factory(_figure)
else:
FixedMarginAxes = fixed_margin_axes(plt.Axes, [1, 0.5, 0.75, 0.5])
_axes = FixedMarginAxes(_figure)
_figure.add_axes(_axes)
_axes = _figure.add_subplot(111)
fix_margins(_axes, [1, 0.25, 0.50, 0.25])

return _figure, _axes

Expand Down
57 changes: 26 additions & 31 deletions glue/utils/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,47 +178,42 @@ def point_contour(x, y, data):
return xy


def fixed_margin_axes(ax_class, margins=[1, 1, 1, 1]):
"""
Class factory to make an axes class that will preserve fixed margins when
figure is resized.
class AxesResizer(object):

Parameters
----------
ax_class : matplotlib.axes.Axes
The axes class to wrap
margins : iterable
The margins, in inches. The order of the margins is
``[left, right, bottom, top]``
"""
def __init__(self, ax, margins):

# Note that margins gets used directly in get_fixed_margin_rect and we
# don't pass it through the axes class.
self.ax = ax
self.margins = margins

def get_fixed_margin_rect(fig):
def on_resize(self, event):

fig_width = fig.get_figwidth()
fig_height = fig.get_figheight()
fig_width = self.ax.figure.get_figwidth()
fig_height = self.ax.figure.get_figheight()

x0 = margins[0] / fig_width
x1 = 1 - margins[1] / fig_width
y0 = margins[2] / fig_height
y1 = 1 - margins[3] / fig_height
x0 = self.margins[0] / fig_width
x1 = 1 - self.margins[1] / fig_width
y0 = self.margins[2] / fig_height
y1 = 1 - self.margins[3] / fig_height

dx = max(0.01, x1 - x0)
dy = max(0.01, y1 - y0)

return [x0, y0, dx, dy]
self.ax.set_position([x0, y0, dx, dy])
self.ax.figure.canvas.draw()

class ax_subclass(ax_class):

def __init__(self, fig, **kwargs):
rect = get_fixed_margin_rect(fig)
super(ax_subclass, self).__init__(fig, rect, **kwargs)
def fix_margins(axes, margins=[1, 1, 1, 1]):
"""
Make sure margins of axes stay fixed.
def draw(self, *args, **kwargs):
rect = get_fixed_margin_rect(self.figure)
self.set_position(rect)
super(ax_subclass, self).draw(*args, **kwargs)
Parameters
----------
ax_class : matplotlib.axes.Axes
The axes class for which to fix the margins
margins : iterable
The margins, in inches. The order of the margins is
``[left, right, bottom, top]``
"""

return ax_subclass
resizer = AxesResizer(axes, margins)
axes.figure.canvas.mpl_connect('resize_event', resizer.on_resize)

0 comments on commit f9546ca

Please sign in to comment.