Discussion:
[Matplotlib-users] sharex with one figure aspect = 1.0
Mark Bakker
2015-04-07 19:52:53 UTC
Permalink
Hello list,

I want to axes above each other. They share the x-axis. The top figure has
'aspect=1' (it is a map), the bottom figure shows a cross-section along a
horizontal line on the map, so it doesn't have 'aspect=1'. When I do this
with code, for example like this:

fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')

then the physical size of the top axes is much sorter than the physical
size of the bottom axes (although they are poperly linked, as they have the
same data limit, and when zooming in the top figure, the bottom figure
adjusts). It just looks weird, as the size of the horizontal axis of the
bottom figure should have the same physical size as the horizontal axis of
the top figure. This used to be possible (a few years ago; haven't tried it
for a while). Is there a way to do it with the current matpotlib? (1.4.3)

Thanks,

Mark
Thomas Caswell
2015-04-08 10:50:45 UTC
Permalink
What are the data limits you are using?

I suspect they you are over constraining the system/order of operations
issue. Try dropping the adjustable setting and pre setting both the data
limits and the approximate size in figure fraction (ex via grid spec) of
the axes.

Tom
Post by Mark Bakker
Hello list,
I want to axes above each other. They share the x-axis. The top figure has
'aspect=1' (it is a map), the bottom figure shows a cross-section along a
horizontal line on the map, so it doesn't have 'aspect=1'. When I do this
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
then the physical size of the top axes is much sorter than the physical
size of the bottom axes (although they are poperly linked, as they have the
same data limit, and when zooming in the top figure, the bottom figure
adjusts). It just looks weird, as the size of the horizontal axis of the
bottom figure should have the same physical size as the horizontal axis of
the top figure. This used to be possible (a few years ago; haven't tried it
for a while). Is there a way to do it with the current matpotlib? (1.4.3)
Thanks,
Mark
------------------------------------------------------------
------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live
exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual-
event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_
campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Mark Bakker
2015-04-08 12:13:11 UTC
Permalink
Thanks, Thomas.

That works indeed, but it doesn't make the figure adjustable, which is what
I wanted (that the physical size of the axes changes while the aspect ratio
is fixed to 1). I guess that functionality has been taken out.

Mark
Post by Thomas Caswell
What are the data limits you are using?
I suspect they you are over constraining the system/order of operations
issue. Try dropping the adjustable setting and pre setting both the data
limits and the approximate size in figure fraction (ex via grid spec) of
the axes.
Tom
Post by Mark Bakker
Hello list,
I want to axes above each other. They share the x-axis. The top figure
has 'aspect=1' (it is a map), the bottom figure shows a cross-section along
a horizontal line on the map, so it doesn't have 'aspect=1'. When I do this
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
then the physical size of the top axes is much sorter than the physical
size of the bottom axes (although they are poperly linked, as they have the
same data limit, and when zooming in the top figure, the bottom figure
adjusts). It just looks weird, as the size of the horizontal axis of the
bottom figure should have the same physical size as the horizontal axis of
the top figure. This used to be possible (a few years ago; haven't tried it
for a while). Is there a way to do it with the current matpotlib? (1.4.3)
Thanks,
Mark
------------------------------------------------------------
------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live
exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual-
event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_
campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Thomas Caswell
2015-04-08 12:16:20 UTC
Permalink
Can you please provide a minimal, but complete and runnable example of what
you are doing?
Post by Mark Bakker
Thanks, Thomas.
That works indeed, but it doesn't make the figure adjustable, which is
what I wanted (that the physical size of the axes changes while the aspect
ratio is fixed to 1). I guess that functionality has been taken out.
Mark
Post by Thomas Caswell
What are the data limits you are using?
I suspect they you are over constraining the system/order of operations
issue. Try dropping the adjustable setting and pre setting both the data
limits and the approximate size in figure fraction (ex via grid spec) of
the axes.
Tom
Post by Mark Bakker
Hello list,
I want to axes above each other. They share the x-axis. The top figure
has 'aspect=1' (it is a map), the bottom figure shows a cross-section along
a horizontal line on the map, so it doesn't have 'aspect=1'. When I do this
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
then the physical size of the top axes is much sorter than the physical
size of the bottom axes (although they are poperly linked, as they have the
same data limit, and when zooming in the top figure, the bottom figure
adjusts). It just looks weird, as the size of the horizontal axis of the
bottom figure should have the same physical size as the horizontal axis of
the top figure. This used to be possible (a few years ago; haven't tried it
for a while). Is there a way to do it with the current matpotlib? (1.4.3)
Thanks,
Mark
------------------------------------------------------------
------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live
exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual-
event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_
campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Mark Bakker
2015-04-08 12:20:48 UTC
Permalink
import matplotlib.pyplot as plt
%matplotlib qt
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
plt.show()

This used to create two axes of the same horizontal size. What it does now
is that it scales the upper axis so that the aspect=1.0 by changing the
physical size of the axis. But the physical size of the lower axis is not
changed, while this used to be the case in the past (but that may have been
a few years back). That sure used to be the desired behavior.

Thanks for your help,

Mark
Post by Thomas Caswell
Can you please provide a minimal, but complete and runnable example of
what you are doing?
Post by Mark Bakker
Thanks, Thomas.
That works indeed, but it doesn't make the figure adjustable, which is
what I wanted (that the physical size of the axes changes while the aspect
ratio is fixed to 1). I guess that functionality has been taken out.
Mark
Post by Thomas Caswell
What are the data limits you are using?
I suspect they you are over constraining the system/order of operations
issue. Try dropping the adjustable setting and pre setting both the data
limits and the approximate size in figure fraction (ex via grid spec) of
the axes.
Tom
Post by Mark Bakker
Hello list,
I want to axes above each other. They share the x-axis. The top figure
has 'aspect=1' (it is a map), the bottom figure shows a cross-section along
a horizontal line on the map, so it doesn't have 'aspect=1'. When I do this
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
then the physical size of the top axes is much sorter than the physical
size of the bottom axes (although they are poperly linked, as they have the
same data limit, and when zooming in the top figure, the bottom figure
adjusts). It just looks weird, as the size of the horizontal axis of the
bottom figure should have the same physical size as the horizontal axis of
the top figure. This used to be possible (a few years ago; haven't tried it
for a while). Is there a way to do it with the current matpotlib? (1.4.3)
Thanks,
Mark
------------------------------------------------------------
------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live
exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual-
event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_
campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Thomas Caswell
2015-04-08 12:53:57 UTC
Permalink
What version had this behavior? I recall some work on how aspect worked,
but not exactly what we did. I see why it is useful, but on the other hand
that sort of coupling seems like could cause some trouble if we are not
careful. This all come back to we need a real layout manager/constraint
solver (which no one has yet had time to address).

For now I think this will do what you want:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

fig, ax_top = plt.subplots()
ax_top.set_aspect(1)
divider = make_axes_locatable(ax_top)
bax_bottom = divider.append_axes('bottom', 1, pad=0.1,
sharex=ax_top)


Please don't use `plt.setp`, it is a MATLABism that I think is past it's
time.
Post by Mark Bakker
import matplotlib.pyplot as plt
%matplotlib qt
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
plt.show()
This used to create two axes of the same horizontal size. What it does now
is that it scales the upper axis so that the aspect=1.0 by changing the
physical size of the axis. But the physical size of the lower axis is not
changed, while this used to be the case in the past (but that may have been
a few years back). That sure used to be the desired behavior.
Thanks for your help,
Mark
Post by Thomas Caswell
Can you please provide a minimal, but complete and runnable example of
what you are doing?
Post by Mark Bakker
Thanks, Thomas.
That works indeed, but it doesn't make the figure adjustable, which is
what I wanted (that the physical size of the axes changes while the aspect
ratio is fixed to 1). I guess that functionality has been taken out.
Mark
Post by Thomas Caswell
What are the data limits you are using?
I suspect they you are over constraining the system/order of operations
issue. Try dropping the adjustable setting and pre setting both the data
limits and the approximate size in figure fraction (ex via grid spec) of
the axes.
Tom
Post by Mark Bakker
Hello list,
I want to axes above each other. They share the x-axis. The top figure
has 'aspect=1' (it is a map), the bottom figure shows a cross-section along
a horizontal line on the map, so it doesn't have 'aspect=1'. When I do this
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
then the physical size of the top axes is much sorter than the
physical size of the bottom axes (although they are poperly linked, as they
have the same data limit, and when zooming in the top figure, the bottom
figure adjusts). It just looks weird, as the size of the horizontal axis of
the bottom figure should have the same physical size as the horizontal axis
of the top figure. This used to be possible (a few years ago; haven't tried
it for a while). Is there a way to do it with the current matpotlib? (1.4.3)
Thanks,
Mark
------------------------------------------------------------
------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live
exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual-
event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_
campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Jody Klymak
2015-04-08 17:04:57 UTC
Permalink
Following up on this, I’d like to complain about set_aspect()


If I do:

import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_ylim(0,1.)
axes[0].set_aspect(1.)
plt.show()

the x-axis goes from 0. to 1., but axes[0]’s y-axis goes from 0.32 to 0.67. Swapping the order of the y_lim call doesn’t help. This is very un-intuitive, as I’d expect set_ylim() to set what data I see no matter what else is happening w/ the plot.

I see that
axes[0].set_aspect(1.,adjustable=‘box-forced’)
will give the desired behaviour, but I really think it should be the default, not adjustable=‘datalim'. I had no idea set_aspect() had this parameter until today, and have had several cursing matches with set_aspect as it kept changing my explicitly set data limits. set_ylim() should set the y limits.

Just my opinion. Maybe there is a reason for the default, but I really think the data view should be prioritized over the shape of the axis.

Thanks, Jody
What version had this behavior? I recall some work on how aspect worked, but not exactly what we did. I see why it is useful, but on the other hand that sort of coupling seems like could cause some trouble if we are not careful. This all come back to we need a real layout manager/constraint solver (which no one has yet had time to address).
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax_top = plt.subplots()
ax_top.set_aspect(1)
divider = make_axes_locatable(ax_top)
bax_bottom = divider.append_axes('bottom', 1, pad=0.1,
sharex=ax_top)
Please don't use `plt.setp`, it is a MATLABism that I think is past it's time.
import matplotlib.pyplot as plt
%matplotlib qt
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
plt.show()
This used to create two axes of the same horizontal size. What it does now is that it scales the upper axis so that the aspect=1.0 by changing the physical size of the axis. But the physical size of the lower axis is not changed, while this used to be the case in the past (but that may have been a few years back). That sure used to be the desired behavior.
Thanks for your help,
Mark
Can you please provide a minimal, but complete and runnable example of what you are doing?
Thanks, Thomas.
That works indeed, but it doesn't make the figure adjustable, which is what I wanted (that the physical size of the axes changes while the aspect ratio is fixed to 1). I guess that functionality has been taken out.
Mark
What are the data limits you are using?
I suspect they you are over constraining the system/order of operations issue. Try dropping the adjustable setting and pre setting both the data limits and the approximate size in figure fraction (ex via grid spec) of the axes.
Tom
Hello list,
fig, axes = plt.subplots(nrows=2,sharex=True)
plt.setp(axes[0], aspect=1.0, adjustable='box-forced')
then the physical size of the top axes is much sorter than the physical size of the bottom axes (although they are poperly linked, as they have the same data limit, and when zooming in the top figure, the bottom figure adjusts). It just looks weird, as the size of the horizontal axis of the bottom figure should have the same physical size as the horizontal axis of the top figure. This used to be possible (a few years ago; haven't tried it for a while). Is there a way to do it with the current matpotlib? (1.4.3)
Thanks,
Mark
------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- <http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual-> event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users <https://lists.sourceforge.net/lists/listinfo/matplotlib-users>
------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
--
Jody Klymak
http://web.uvic.ca/~jklymak/
Eric Firing
2015-04-08 18:02:43 UTC
Permalink
Following up on this, I’d like to complain about set_aspect()…
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_ylim(0,1.)
axes[0].set_aspect(1.)
plt.show()
the x-axis goes from 0. to 1., but axes[0]’s y-axis goes from 0.32 to
0.67. Swapping the order of the y_lim call doesn’t help. This is very
un-intuitive, as I’d expect set_ylim() to set what data I see no matter
what else is happening w/ the plot.
I see that
axes[0].set_aspect(1.,adjustable=‘box-forced’)
will give the desired behaviour, but I really think it should be the
default, not adjustable=‘datalim'. I had no idea set_aspect() had this
parameter until today, and have had several cursing matches with
set_aspect as it kept changing my explicitly set data limits. set_ylim()
should set the y limits.
Just my opinion. Maybe there is a reason for the default, but I really
think the data view should be prioritized over the shape of the axis.
Jody,

I'm the guilty party for most of how set_aspect works. I developed it a
long time ago. Yes, there was a reason--still is, I'm 99% sure--but I
don't remember everything, and don't want to take the time now to
reconstruct the whole rationale. When I was developing the behavior, I
was paying a lot of attention to what happens under various scenarios of
resizing and reshaping the window, and turning options on and off.
There are some basic conflicts that arise when shared axes are combined
with fixed aspect ratios, autoscaling, and gui-driven reshaping.
Sometimes 'box-forced' does what people want, maybe more often than not;
but I'm pretty sure it can lead to trouble, which is the reason it is
not the default.

Eric
Thanks, Jody
Jody Klymak
2015-04-08 18:43:25 UTC
Permalink
Hi Eric,
Post by Eric Firing
I'm the guilty party for most of how set_aspect works. I developed it a
long time ago. Yes, there was a reason--still is, I'm 99% sure--but I
don't remember everything, and don't want to take the time now to
reconstruct the whole rationale. When I was developing the behavior, I
was paying a lot of attention to what happens under various scenarios of
resizing and reshaping the window, and turning options on and off.
There are some basic conflicts that arise when shared axes are combined
with fixed aspect ratios, autoscaling, and gui-driven reshaping.
Sometimes 'box-forced' does what people want, maybe more often than not;
but I'm pretty sure it can lead to trouble, which is the reason it is
not the default.
OK, first my apologies:

import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[0].set_ylim([0,24])
axes[0].set_xlim([0,12])
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()

Works as I'd expect. axes[0] gets shrunk in the x dimension to make the aspect ratio 1.

However:

import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[0].set_ylim([0,24])
axes[0].set_xlim([0,12])
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()

does not work as I'd expect. axes[0]'s ylim gets changed so that the line is no longer viewable (= 10-14). In my opinion, the two calls should work the same, except in the second case, axes[1]'s xlim should be 0-12.

Even worse, if I use the same aspect ratio in axes[1], they *both* do not show all the data:

axes[0].set_aspect(1.)

It appears here that with sharex=True the shape of the axis no longer becomes mutable when set_aspect() is used, whereas if sharex=False set_aspect() can change the axis shape. I don't see any reason for sharex to foist this behaviour onto set_aspect().

I guess the workaround is don't use sharex=True, but I actually think this is a bug.

Thanks, Jody

--
Jody Klymak
http://web.uvic.ca/~jklymak/
Eric Firing
2015-04-08 19:32:14 UTC
Permalink
Post by Jody Klymak
Hi Eric,
Post by Eric Firing
I'm the guilty party for most of how set_aspect works. I developed it a
long time ago. Yes, there was a reason--still is, I'm 99% sure--but I
don't remember everything, and don't want to take the time now to
reconstruct the whole rationale. When I was developing the behavior, I
was paying a lot of attention to what happens under various scenarios of
resizing and reshaping the window, and turning options on and off.
There are some basic conflicts that arise when shared axes are combined
with fixed aspect ratios, autoscaling, and gui-driven reshaping.
Sometimes 'box-forced' does what people want, maybe more often than not;
but I'm pretty sure it can lead to trouble, which is the reason it is
not the default.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[0].set_ylim([0,24])
axes[0].set_xlim([0,12])
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()
Works as I'd expect. axes[0] gets shrunk in the x dimension to make the aspect ratio 1.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[0].set_ylim([0,24])
axes[0].set_xlim([0,12])
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()
does not work as I'd expect. axes[0]'s ylim gets changed so that the line is no longer viewable (= 10-14). In my opinion, the two calls should work the same, except in the second case, axes[1]'s xlim should be 0-12.
If you leave out the set_ylim call, it works. Given that you have
specified set_ylim[0, 24], how is mpl supposed to know what ylim range
you really want, when the axis constraint means it can only plot a small
part of the specified range? Basically, you have set up conflicting
constraints, and mpl failed to resolve the conflict the way you think it
should have. Maybe that could be improved, but I warn you, it's a
tricky business. Squeeze in one place and things pop out somewhere else.

Eric
Post by Jody Klymak
axes[0].set_aspect(1.)
It appears here that with sharex=True the shape of the axis no longer becomes mutable when set_aspect() is used, whereas if sharex=False set_aspect() can change the axis shape. I don't see any reason for sharex to foist this behaviour onto set_aspect().
I guess the workaround is don't use sharex=True, but I actually think this is a bug.
Thanks, Jody
--
Jody Klymak
http://web.uvic.ca/~jklymak/
Jody Klymak
2015-04-08 21:15:03 UTC
Permalink
Hi Eric,
Post by Mark Bakker
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[0].set_ylim([0,24])
axes[0].set_xlim([0,12])
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()
does not work as I'd expect. axes[0]'s ylim gets changed so that the line is no longer viewable (= 10-14). In my opinion, the two calls should work the same, except in the second case, axes[1]'s xlim should be 0-12.
If you leave out the set_ylim call, it works. Given that you have specified set_ylim[0, 24], how is mpl supposed to know what ylim range you really want, when the axis constraint means it can only plot a small part of the specified range?
It doesn't for me:

import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()

still curtails the y limit in axes[0], in my case from ~2.9 to ~6.1 (see attached).
Basically, you have set up conflicting constraints, and mpl failed to resolve the conflict the way you think it should have. Maybe that could be improved, but I warn you, it's a tricky business. Squeeze in one place and things pop out somewhere else.
I'm not clear what the conflicting constraints are. There seems to be an unspoken one that sharex=True means the physical size of the axes must be the same. That constraint doesn't exist if sharex=False, and set_aspect() works as expected. I'm questioning the unspoken constraint, and questioning why set_aspect() (or looking at the code apply_aspect()) needs to know about shared axes at all. No doubt there is a use case I'm missing...

I *can* see the issue if we think setting aspect ratios should *not* change the size of the axes, because changing the aspect ratio changes the data limits and then you have a problem checking all the shared axes to see which one has the largest data limits. Its particularly problematic because I think that apply_aspect() is only called at draw()-time. That seems a hard problem, but I'm not sure what the use case is for it, so I have trouble wrapping my head around it.

Thanks, Jody


--
Jody Klymak
http://web.uvic.ca/~jklymak/
Eric Firing
2015-04-08 22:18:22 UTC
Permalink
Post by Jody Klymak
Hi Eric,
Post by Eric Firing
Post by Mark Bakker
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[0].set_ylim([0,24])
axes[0].set_xlim([0,12])
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()
does not work as I'd expect. axes[0]'s ylim gets changed so that the
line is no longer viewable (= 10-14). In my opinion, the two calls
should work the same, except in the second case, axes[1]'s xlim
should be 0-12.
If you leave out the set_ylim call, it works. Given that you have
specified set_ylim[0, 24], how is mpl supposed to know what ylim range
you really want, when the axis constraint means it can only plot a
small part of the specified range?
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2,sharex=True)
axes[0].set_aspect(1.)
axes[0].plot(np.arange(10),np.arange(10))
axes[1].plot(np.arange(10),np.arange(10)*2.)
plt.show()
still curtails the y limit in axes[0], in my case from ~2.9 to ~6.1 (see attached).
Jody, you told it you want x to go from 0 to 12, and have an aspect
ratio of 1. It is doing exactly that. Are you expecting it to override
your xlim specification?
Post by Jody Klymak
Post by Eric Firing
Basically, you have set up conflicting constraints, and mpl failed
to resolve the conflict the way you think it should have. Maybe that
could be improved, but I warn you, it's a tricky business. Squeeze in
one place and things pop out somewhere else.
I'm not clear what the conflicting constraints are. There seems to be
an unspoken one that sharex=True means the physical size of the axes
must be the same. That constraint doesn't exist if sharex=False, and
set_aspect() works as expected. I'm questioning the unspoken
constraint, and questioning why set_aspect() (or looking at the code
apply_aspect()) needs to know about shared axes at all. No doubt there
is a use case I'm missing...
Yes, sharex=True means the x-axis is identical. It's shared. That's
just what it means, and what it has always meant. That's what it is
for--to lock together the x axes of two or more Axes.
Post by Jody Klymak
I *can* see the issue if we think setting aspect ratios should *not*
change the size of the axes, because changing the aspect ratio changes
the data limits and then you have a problem checking all the shared axes
to see which one has the largest data limits. Its particularly
problematic because I think that apply_aspect() is only called at
draw()-time. That seems a hard problem, but I'm not sure what the use
case is for it, so I have trouble wrapping my head around it.
The use case for what--calling apply_aspect at draw time? That's the
only time it knows everything it needs to know in the general case, when
there might be pan/zoom/reshape events.

Eric
Post by Jody Klymak
Thanks, Jody
--
Jody Klymak
http://web.uvic.ca/~jklymak/
------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Eric Firing
2015-04-08 18:05:04 UTC
Permalink
Post by Jody Klymak
Maybe there is a reason for the default, but I really think the data
view should be prioritized over the shape of the axis.
I forgot to include: I was trying to make everything sane (and
reversible) under zoom and pan as well as reshaping and resizing.
Loading...