I noticed that when you offset the spines of an Axes object, the labels, ticks, and ticklabels/formatting get mostly cleared. Is this intentional and is there a way to prevent (or undo) it?
It’s probably easiest to just look at a notebook:
http://nbviewer.ipython.org/gist/phobson/8818648
That notebook contains a proposed solution from Stack Overflow. Unfortunately, minor ticks and labels are missed (and I can’t understand why as the values are contained in the properties dictionary of the spines).
Background: I’m trying to add an offset kwarg to the despine function in seaborn (https://github.com/mwaskom/seaborn/pull/92). Point of mentioning that is that to make this work, we need to be able to offset the spines after plotting and formatting ticks.
Alternatively, if there was a way to specify a default offset in rcParams before a figure and axes were even created, that might work too.
···
Related to that, when I use the SO solution, about 50% of the time the axes labels are rendered as the label objects, not text. Whatever triggers that doesn’t seem to be deterministic. Resetting the notebook will fix it or break it – there’s no telling how it’s going to go. Here’s the exact same notebook as above, with the mangled figure at the bottom.
http://nbviewer.ipython.org/gist/phobson/8818680
Cheers,
-Paul
[…]
Paul, I may have encountered the same issue a few years ago. May I
suggest that you look at the mailing list thread from that time [1],
try the patch in the thread, and see whether your issue is resolved?
This solution doesn’t provide a work-around in your code, but it may
fix the problem at the root. I took a brief look at the current
state of spines.py, and I found only the same instances of
“self.axis.cla()” that the patch changes to
“self.axis.reset_ticks()”.
Kind regards,
Stan
[1] ,
29 Sep. 2010.
···
On 2014-02-05 02:26, Paul Hobson wrote:
I noticed that when you offset the spines of an
Axes object, the labels, ticks, and ticklabels/formatting get
mostly cleared. Is this intentional and is there a way to
prevent (or undo) it?
http://matplotlib.1069221.n5.nabble.com/Spine-set-position-unexpectedly-clears-axis-td37865.html
Paul, I just found the work-around that I used in my code. Define
the following function:
(The mention of v. 1.0.0 in the docstring is just the version I was
using at the time, not necessarily the earliest version with this
issue.) Then replace method calls like “spine.set_position(pos)”
with the function call “set_spine_position(spine, pos)”. I hope this
helps.
···
On 2014-03-24 14:08, Stan West wrote:
May I suggest that you look at the mailing list thread from that
time [1], try the patch in the thread, and see whether your issue
is resolved? This solution doesn’t provide a work-around in your
code, but it may fix the problem at the root.
def set_spine_position(spine, position):
"""
Set the spine's position without resetting an associated axis.
As of matplotlib v. 1.0.0, if a spine has an associated axis, then spine.set_position() calls axis.cla(), which resets locators, formatters, etc. We temporarily replace that call with axis.reset_ticks(), which is sufficient for our purposes.
"""
axis = spine.axis
if axis is not None:
cla = axis.cla
axis.cla = axis.reset_ticks
spine.set_position(position)
if axis is not None:
axis.cla = cla
Wow. Thanks so much, Stan! This is a huge help and works just as I need it to.
Much appreciated!
···
On Mon, Mar 24, 2014 at 11:26 AM, Stan West <stan.west@…595…> wrote:
On 2014-03-24 14:08, Stan West wrote:
May I suggest that you look at the mailing list thread from that
time [1], try the patch in the thread, and see whether your issue
is resolved? This solution doesn’t provide a work-around in your
code, but it may fix the problem at the root.
Paul, I just found the work-around that I used in my code. Define
the following function:
def set_spine_position(spine, position):
"""
Set the spine's position without resetting an associated axis.
As of matplotlib v. 1.0.0, if a spine has an associated axis, then spine.set_position() calls axis.cla(), which resets locators, formatters, etc. We temporarily replace that call with axis.reset_ticks(), which is sufficient for our purposes.
"""
axis = spine.axis
if axis is not None:
cla = axis.cla
axis.cla = axis.reset_ticks
spine.set_position(position)
if axis is not None:
axis.cla = cla
(The mention of v. 1.0.0 in the docstring is just the version I was
using at the time, not necessarily the earliest version with this
issue.) Then replace method calls like “spine.set_position(pos)”
with the function call “set_spine_position(spine, pos)”. I hope this
helps.