-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Implementation of separate horizontal/vertical axes padding to the axis_grid toolkit #2466
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
Changes from all commits
fb52e4f
3f988d4
856a82f
d089d34
318dd26
f02d214
6fb8607
ccd6ee0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,6 @@ | ||
from __future__ import (absolute_import, division, print_function, | ||
unicode_literals) | ||
|
||
import six | ||
|
||
import matplotlib.cbook as cbook | ||
|
||
import matplotlib.pyplot as plt | ||
|
@@ -14,12 +12,19 @@ | |
import matplotlib.lines as mlines | ||
import matplotlib.ticker as ticker | ||
|
||
from matplotlib.gridspec import SubplotSpec, GridSpec | ||
from matplotlib.gridspec import SubplotSpec | ||
|
||
from .axes_divider import Size, SubplotDivider, LocatableAxes, Divider | ||
|
||
#import numpy as np | ||
|
||
def _extend_axes_pad(value): | ||
# Check whether a list/tuple/array or scalar has been passed | ||
ret = value | ||
if not hasattr(ret, "__getitem__"): | ||
ret = (value, value) | ||
return ret | ||
|
||
def _tick_only(ax, bottom_on, left_on): | ||
bottom_off = not bottom_on | ||
left_off = not left_on | ||
|
@@ -70,7 +75,7 @@ def _config_axes_deprecated(self, X, Y): | |
class CbarAxesBase(object): | ||
|
||
def colorbar(self, mappable, **kwargs): | ||
locator=kwargs.pop("locator", None) | ||
locator = kwargs.pop("locator", None) | ||
|
||
if locator is None: | ||
if "ticks" not in kwargs: | ||
|
@@ -83,9 +88,9 @@ def colorbar(self, mappable, **kwargs): | |
|
||
self.hold(True) | ||
if self.orientation in ["top", "bottom"]: | ||
orientation="horizontal" | ||
orientation = "horizontal" | ||
else: | ||
orientation="vertical" | ||
orientation = "vertical" | ||
|
||
cb = Colorbar(self, mappable, orientation=orientation, **kwargs) | ||
self._config_axes() | ||
|
@@ -146,7 +151,7 @@ def toggle_label(self, b): | |
|
||
class CbarAxes(CbarAxesBase, LocatableAxes): | ||
def __init__(self, *kl, **kwargs): | ||
orientation=kwargs.pop("orientation", None) | ||
orientation = kwargs.pop("orientation", None) | ||
if orientation is None: | ||
raise ValueError("orientation must be specified") | ||
self.orientation = orientation | ||
|
@@ -201,6 +206,8 @@ def __init__(self, fig, | |
================ ======== ========================================= | ||
direction "row" [ "row" | "column" ] | ||
axes_pad 0.02 float| pad between axes given in inches | ||
or tuple-like of floats, | ||
(horizontal padding, vertical padding) | ||
add_all True [ True | False ] | ||
share_all False [ True | False ] | ||
share_x True [ True | False ] | ||
|
@@ -239,8 +246,8 @@ def __init__(self, fig, | |
axes_class, axes_class_args = axes_class | ||
|
||
self.axes_all = [] | ||
self.axes_column = [[] for i in range(self._ncols)] | ||
self.axes_row = [[] for i in range(self._nrows)] | ||
self.axes_column = [[] for _ in range(self._ncols)] | ||
self.axes_row = [[] for _ in range(self._nrows)] | ||
|
||
|
||
h = [] | ||
|
@@ -264,8 +271,8 @@ def __init__(self, fig, | |
rect = self._divider.get_position() | ||
|
||
# reference axes | ||
self._column_refax = [None for i in range(self._ncols)] | ||
self._row_refax = [None for i in range(self._nrows)] | ||
self._column_refax = [None for _ in range(self._ncols)] | ||
self._row_refax = [None for _ in range(self._nrows)] | ||
self._refax = None | ||
|
||
for i in range(self.ngrids): | ||
|
@@ -314,22 +321,24 @@ def __init__(self, fig, | |
|
||
|
||
def _init_axes_pad(self, axes_pad): | ||
axes_pad = _extend_axes_pad(axes_pad) | ||
self._axes_pad = axes_pad | ||
|
||
self._horiz_pad_size = Size.Fixed(axes_pad) | ||
self._vert_pad_size = Size.Fixed(axes_pad) | ||
self._horiz_pad_size = Size.Fixed(axes_pad[0]) | ||
self._vert_pad_size = Size.Fixed(axes_pad[1]) | ||
|
||
|
||
def _update_locators(self): | ||
|
||
h = [] | ||
|
||
h_ax_pos = [] | ||
h_cb_pos = [] | ||
#h_cb_pos = [] | ||
|
||
for ax in self._column_refax: | ||
for _ in self._column_refax: | ||
#if h: h.append(Size.Fixed(self._axes_pad)) | ||
if h: h.append(self._horiz_pad_size) | ||
if h: | ||
h.append(self._horiz_pad_size) | ||
|
||
h_ax_pos.append(len(h)) | ||
|
||
|
@@ -339,10 +348,11 @@ def _update_locators(self): | |
v = [] | ||
|
||
v_ax_pos = [] | ||
v_cb_pos = [] | ||
for ax in self._row_refax[::-1]: | ||
#v_cb_pos = [] | ||
for _ in self._row_refax[::-1]: | ||
#if v: v.append(Size.Fixed(self._axes_pad)) | ||
if v: v.append(self._vert_pad_size) | ||
if v: | ||
v.append(self._vert_pad_size) | ||
|
||
v_ax_pos.append(len(v)) | ||
sz = Size.Scaled(1) | ||
|
@@ -372,6 +382,8 @@ def _get_col_row(self, n): | |
def __getitem__(self, i): | ||
return self.axes_all[i] | ||
|
||
def __len__(self): | ||
return len(self.axes_all) | ||
|
||
def get_geometry(self): | ||
""" | ||
|
@@ -382,14 +394,22 @@ def get_geometry(self): | |
|
||
def set_axes_pad(self, axes_pad): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we have both of these functions? They are identical, one should either be an alias for the other. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The other function I am referring to is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know why we have them, so I have done as you suggested them. |
||
"set axes_pad" | ||
axes_pad = _extend_axes_pad(axes_pad) | ||
self._axes_pad = axes_pad | ||
|
||
self._horiz_pad_size.fixed_size = axes_pad | ||
self._vert_pad_size.fixed_size = axes_pad | ||
|
||
# These two lines actually differ from ones in _init_axes_pad | ||
self._horiz_pad_size.fixed_size = axes_pad[0] | ||
self._vert_pad_size.fixed_size = axes_pad[1] | ||
|
||
def get_axes_pad(self): | ||
"get axes_pad" | ||
""" | ||
get axes_pad | ||
|
||
Returns | ||
------- | ||
tuple | ||
Padding in inches, (horizontal pad, vertical pad) | ||
""" | ||
return self._axes_pad | ||
|
||
def set_aspect(self, aspect): | ||
|
@@ -495,6 +515,8 @@ def __init__(self, fig, | |
================ ======== ========================================= | ||
direction "row" [ "row" | "column" ] | ||
axes_pad 0.02 float| pad between axes given in inches | ||
or tuple-like of floats | ||
(horizontal padding, vertical padding) | ||
add_all True [ True | False ] | ||
share_all False [ True | False ] | ||
aspect True [ True | False ] | ||
|
@@ -521,12 +543,15 @@ def __init__(self, fig, | |
|
||
self.ngrids = ngrids | ||
|
||
axes_pad = _extend_axes_pad(axes_pad) | ||
self._axes_pad = axes_pad | ||
|
||
self._colorbar_mode = cbar_mode | ||
self._colorbar_location = cbar_location | ||
if cbar_pad is None: | ||
self._colorbar_pad = axes_pad | ||
# horizontal or vertical arrangement? | ||
self._colorbar_pad = axes_pad[0] \ | ||
if cbar_location in ("left", "right") else axes_pad[1] | ||
else: | ||
self._colorbar_pad = cbar_pad | ||
|
||
|
@@ -552,8 +577,8 @@ def __init__(self, fig, | |
|
||
|
||
self.axes_all = [] | ||
self.axes_column = [[] for i in range(self._ncols)] | ||
self.axes_row = [[] for i in range(self._nrows)] | ||
self.axes_column = [[] for _ in range(self._ncols)] | ||
self.axes_row = [[] for _ in range(self._nrows)] | ||
|
||
self.cbar_axes = [] | ||
|
||
|
@@ -578,8 +603,8 @@ def __init__(self, fig, | |
rect = self._divider.get_position() | ||
|
||
# reference axes | ||
self._column_refax = [None for i in range(self._ncols)] | ||
self._row_refax = [None for i in range(self._nrows)] | ||
self._column_refax = [None for _ in range(self._ncols)] | ||
self._row_refax = [None for _ in range(self._nrows)] | ||
self._refax = None | ||
|
||
for i in range(self.ngrids): | ||
|
@@ -658,8 +683,9 @@ def _update_locators(self): | |
self.cbar_axes[0].set_axes_locator(locator) | ||
self.cbar_axes[0].set_visible(True) | ||
|
||
for col,ax in enumerate(self._column_refax): | ||
if h: h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) | ||
for col, ax in enumerate(self._column_refax): | ||
if h: | ||
h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) | ||
|
||
if ax: | ||
sz = Size.AxesX(ax) | ||
|
@@ -687,8 +713,9 @@ def _update_locators(self): | |
|
||
v_ax_pos = [] | ||
v_cb_pos = [] | ||
for row,ax in enumerate(self._row_refax[::-1]): | ||
if v: v.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) | ||
for row, ax in enumerate(self._row_refax[::-1]): | ||
if v: | ||
v.append(self._vert_pad_size) #Size.Fixed(self._axes_pad)) | ||
|
||
if ax: | ||
sz = Size.AxesY(ax) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to add an
axes_pad_vert
(or similarly named) which defaults toNone
-> set equal toaxes_pad
else,axes_pad
is used for horizontal andaxes_pad_vert
is used for vertical? It eliminates the need for the extend function and leads to simpler api and code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I don't insist on anything, there are some good reasons for my approach:
np.zeros(4)
ornp.zeros((4,))
for a 1D array, but you have to writenp.zeros((4,2))
for a 2D array. Allowing passing a scalar instead of a tuple makes it more convenient for common cases, although it complicates implementationaxes_pad_vert
argument in the middle would, adding it at the end wouldn't, but that would lack some sense)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I had been thinking about them as pure kwargs and forgot about calling with only positional arguments, I now agree as written is the right way to do this.