Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don’t use tight layout as it causes bouncing around of axes #745

Merged
merged 11 commits into from
Sep 13, 2015
7 changes: 2 additions & 5 deletions glue/clients/histogram_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +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 fix_margins


class UpdateProperty(CallbackProperty):
Expand Down Expand Up @@ -58,15 +59,11 @@ def __init__(self, data, figure, artist_container=None):

self._artists = artist_container or LayerArtistContainer()
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 = {}

try:
self._axes.figure.set_tight_layout(True)
except AttributeError: # pragma: nocover (matplotlib < 1.1)
pass

@property
def bins(self):
""" An array of bin edges for the histogram.
Expand Down
6 changes: 0 additions & 6 deletions glue/clients/profile_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,6 @@ def set_visible(self, visible):

def _build_axes(figure):

# tight-layout clobbers manual positioning
try:
figure.set_tight_layout(False)
except AttributeError: # old MPL
pass

ax2 = figure.add_subplot(122)
ax1 = figure.add_subplot(121, sharex=ax2)

Expand Down
12 changes: 6 additions & 6 deletions glue/clients/viz_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import matplotlib.pyplot as plt
from ..core.client import Client
from ..core import Data
from ..utils.matplotlib import fix_margins
from .layer_artist import LayerArtistContainer

__all__ = ['VizClient', 'GenericMplClient']
Expand Down Expand Up @@ -136,8 +137,9 @@ def init_layer(self, layer):


def init_mpl(figure, axes, wcs=False, axes_factory=None):
if axes is not None and figure is not None and \
axes.figure is not figure:

if (axes is not None and figure is not None and
axes.figure is not figure):
raise ValueError("Axes and figure are incompatible")

try:
Expand All @@ -153,15 +155,13 @@ def init_mpl(figure, axes, wcs=False, axes_factory=None):
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:
_axes = _figure.add_subplot(1, 1, 1)
try:
_figure.set_tight_layout(True)
except AttributeError: # matplotlib < 1.1
pass
fix_margins(_axes, [1, 0.25, 0.50, 0.25])

return _figure, _axes

Expand Down
4 changes: 0 additions & 4 deletions glue/qt/widgets/mpl_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ def __init__(self):
self.roi_callback = None

self.fig = Figure(facecolor='#ffffff')
try:
self.fig.set_tight_layout(True)
except AttributeError: # matplotlib < 1.1
pass

FigureCanvas.__init__(self, self.fig)
FigureCanvas.setSizePolicy(self,
Expand Down
41 changes: 41 additions & 0 deletions glue/utils/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,44 @@ def point_contour(x, y, data):
return None
xy = xy[0]
return xy


class AxesResizer(object):

def __init__(self, ax, margins):

self.ax = ax
self.margins = margins

def on_resize(self, event):

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

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)

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


def fix_margins(axes, margins=[1, 1, 1, 1]):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about the name freeze_margins? fix could be interpreted as implying that the default is broken.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sounds good

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

"""
Make sure margins of axes stay fixed.

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]``
"""

resizer = AxesResizer(axes, margins)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be nice to store this resizer as an attribute on the axes somewhere, in case downstream code wishes to modify it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that might be a way to customize the margins then, if it's accessible as axes.resizer.margins. I worry a bit about adding axes.resizer though in case it conflicts with Matplotlib in future for any reason. Do you think we should just do it anyway and cross that bridge if it happens?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should worry about future name clashes with resizer

On Friday, September 11, 2015, Thomas Robitaille notifications@github.com
wrote:

In glue/utils/matplotlib.py
#745 (comment):

+def fix_margins(axes, margins=[1, 1, 1, 1]):

  • """
  • Make sure margins of axes stay fixed.
  • 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]`
    
  • """
  • resizer = AxesResizer(axes, margins)

Hmm, that might be a way to customize the margins then, if it's accessible
as axes.resizer.margins. I worry a bit about adding axes.resizer though
in case it conflicts with Matplotlib in future for any reason. Do you think
we should just do it anyway and cross that bridge if it happens?


Reply to this email directly or view it on GitHub
https://github.com/glue-viz/glue/pull/745/files#r39279062.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :)

axes.figure.canvas.mpl_connect('resize_event', resizer.on_resize)