Understanding axes position

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Understanding axes position

Nunzio Losacco
Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
    ax = axes[i]
    ax.set_xlabel('distance [m]')
    if i == 0:
        ax.set_ylabel('depth [m]')
    if i == 1:
        ax.set_yticklabels([])
    ax.invert_yaxis()
    ax.tick_params(direction='in')
    ax.set_aspect('equal')
    odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
    even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

    vmax = 15.
    vmin =  0.
    norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

    color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

    ax.add_patch(odd)
    ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')
 
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Adrien VINCENT
Hi Nunzio,

Quick comment because I do not have much time unfortunately : did you think about using Gridspec (there is a nice tutorial on the Matplotlib website). You may have to set one extra axes instance to "not visible" but overall it may be easier.

Playing a bit with your code, I cannot tell why but when printing `pos` and `ax2.get_position()`, I do not get the same thing, which puzzles me. Maybe somebody else will know why.

Regards,
Adrien

On September 20, 2017 7:06:07 AM PDT, Nunzio Losacco <[hidden email]> wrote:

>Hi all,
>
>what I’m trying to do here is having third plot with its base aligned
>with the others and with reduced height (the final aim is custom
>positioning a colorbar).
>As you can see I’m getting the wrong position. What am I missing?
>
>Thanks for any help
>
>NL
>
># -*- coding: utf-8 -*-
>
>from __future__ import unicode_literals
>import numpy as np
>from scipy.interpolate import griddata
>import matplotlib
>import matplotlib.pyplot as plt
>from matplotlib.patches import Circle
>from matplotlib.pylab import cm
>import matplotlib.colors as colors
>from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
>
>matplotlib.rcParams.update({'font.size': 8})
>
>fig = plt.figure()
>fig.set_size_inches(6.3,6.3)
>
>ax1 = plt.subplot(111)
>divider = make_axes_locatable(ax1)
>ax2 = divider.append_axes('right', size='100%', pad=0.3)
>
>axes = [ax1, ax2]
>ltypes = ['dashed', 'solid']
>
>xi = np.linspace(-18.125, 18.125, 11)
>yi = np.linspace(0, 28, 9)
>xv, yv = np.meshgrid(xi, yi)
>
>xcOdd = 0.2
>zcOdd = 0.725
>xcEven = 0.6
>zcEven = 0.725
>
>maskRadius = 0.15
>
>for i in range(2):
>    ax = axes[i]
>    ax.set_xlabel('distance [m]')
>    if i == 0:
>        ax.set_ylabel('depth [m]')
>    if i == 1:
>        ax.set_yticklabels([])
>    ax.invert_yaxis()
>    ax.tick_params(direction='in')
>    ax.set_aspect('equal')
>odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
>even = Circle((xcEven, zcEven), .15, linewidth=1.2,
>linestyle=ltypes[i], color='k', fill=False)
>
>    vmax = 15.
>    vmin =  0.
>    norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)
>
>color_map =
>matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)),
>"name")
>
>    ax.add_patch(odd)
>    ax.add_patch(even)
>
>pad = 0.03
>width = 0.03
>
>pos = ax2.get_position()
>
>ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width,
>0.7*(pos.ymax-pos.ymin) ])
>
>plt.savefig('prova-vect-paper-test-2.eps', format='eps')
>  
>_______________________________________________
>Matplotlib-users mailing list
>[hidden email]
>https://mail.python.org/mailman/listinfo/matplotlib-users

--
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Jody Klymak
In reply to this post by Nunzio Losacco

Hi Nunzio,

The issue is that you call ax.set_aspect(‘equal’), and that changes the axes box. However, ax.get_position returns the frozen position, i.e. the old position. I don’t see a method to return the new position (and I wonder why get_position behaves this way).

As a work around, you can get the aspect-ratio changed position as:

figW, figH = fig.get_size_inches()
fig_aspect = figH / figW
newpos = pp.shrunk_to_aspect(ax.get_aspect() * ax.get_data_ratio(), pp, fig_aspect).anchored(ax.get_anchor(), pp))

which I appreciate is a bit of a pain….

Cheers, Jody

On 20 Sep 2017, at 7:06, Nunzio Losacco wrote:

Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
ax = axes[i]
ax.set_xlabel('distance [m]')
if i == 0:
ax.set_ylabel('depth [m]')
if i == 1:
ax.set_yticklabels([])
ax.invert_yaxis()
ax.tick_params(direction='in')
ax.set_aspect('equal')
odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

vmax = 15.
vmin = 0.
norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

ax.add_patch(odd)
ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Jody Klymak
Oops.  Just realized you can also just do

Pos =ax._postion

To get the current position.  Of course this could break because you are accessing a private variable.  

Cheers.  Jody

Sent from my iPhone

On Sep 20, 2017, at 11:07, Jody Klymak <[hidden email]> wrote:

Hi Nunzio,

The issue is that you call ax.set_aspect(‘equal’), and that changes the axes box. However, ax.get_position returns the frozen position, i.e. the old position. I don’t see a method to return the new position (and I wonder why get_position behaves this way).

As a work around, you can get the aspect-ratio changed position as:

figW, figH = fig.get_size_inches()
fig_aspect = figH / figW
newpos = pp.shrunk_to_aspect(ax.get_aspect() * ax.get_data_ratio(), pp, fig_aspect).anchored(ax.get_anchor(), pp))

which I appreciate is a bit of a pain….

Cheers, Jody

On 20 Sep 2017, at 7:06, Nunzio Losacco wrote:

Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
ax = axes[i]
ax.set_xlabel('distance [m]')
if i == 0:
ax.set_ylabel('depth [m]')
if i == 1:
ax.set_yticklabels([])
ax.invert_yaxis()
ax.tick_params(direction='in')
ax.set_aspect('equal')
odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

vmax = 15.
vmin = 0.
norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

ax.add_patch(odd)
ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Jody Klymak

On 20 Sep 2017, at 11:32, Klymak Jody wrote:

Oops. Just realized you can also just do

Pos =ax._postion

To get the current position. Of course this could break because you are accessing a private variable.

oops again, no you can’t, you need to use the formula below. The reason is that apply_aspect doesn’t get called until the axes is drawn, so the new _position isn’t set until then.

Sorry, I should have checked before I wrote….

Cheers, Jody

Cheers. Jody

Sent from my iPhone

On Sep 20, 2017, at 11:07, Jody Klymak <[hidden email]> wrote:

Hi Nunzio,

The issue is that you call ax.set_aspect(‘equal’), and that changes the axes box. However, ax.get_position returns the frozen position, i.e. the old position. I don’t see a method to return the new position (and I wonder why get_position behaves this way).

As a work around, you can get the aspect-ratio changed position as:

figW, figH = fig.get_size_inches()
fig_aspect = figH / figW
newpos = pp.shrunk_to_aspect(ax.get_aspect() * ax.get_data_ratio(), pp, fig_aspect).anchored(ax.get_anchor(), pp))
which I appreciate is a bit of a pain….

Cheers, Jody

On 20 Sep 2017, at 7:06, Nunzio Losacco wrote:

Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
ax = axes[i]
ax.set_xlabel('distance [m]')
if i == 0:
ax.set_ylabel('depth [m]')
if i == 1:
ax.set_yticklabels([])
ax.invert_yaxis()
ax.tick_params(direction='in')
ax.set_aspect('equal')
odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

vmax = 15.
vmin = 0.
norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

ax.add_patch(odd)
ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Jody Klymak

As pointed out by Eric Firing (here) you can also do:

ax.set_aspect(1.)
ax.apply_aspect()
pos = ax.get_position(original=False)

Cheers, Jody

On 20 Sep 2017, at 12:30, Jody Klymak wrote:

On 20 Sep 2017, at 11:32, Klymak Jody wrote:

Oops. Just realized you can also just do

Pos =ax._postion

To get the current position. Of course this could break because you are accessing a private variable.

oops again, no you can’t, you need to use the formula below. The reason is that apply_aspect doesn’t get called until the axes is drawn, so the new _position isn’t set until then.

Sorry, I should have checked before I wrote….

Cheers, Jody

Cheers. Jody

Sent from my iPhone

On Sep 20, 2017, at 11:07, Jody Klymak <[hidden email]> wrote:

Hi Nunzio,

The issue is that you call ax.set_aspect(‘equal’), and that changes the axes box. However, ax.get_position returns the frozen position, i.e. the old position. I don’t see a method to return the new position (and I wonder why get_position behaves this way).

As a work around, you can get the aspect-ratio changed position as:

figW, figH = fig.get_size_inches()
fig_aspect = figH / figW
newpos = pp.shrunk_to_aspect(ax.get_aspect() * ax.get_data_ratio(), pp, fig_aspect).anchored(ax.get_anchor(), pp))
which I appreciate is a bit of a pain….

Cheers, Jody

On 20 Sep 2017, at 7:06, Nunzio Losacco wrote:

Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
ax = axes[i]
ax.set_xlabel('distance [m]')
if i == 0:
ax.set_ylabel('depth [m]')
if i == 1:
ax.set_yticklabels([])
ax.invert_yaxis()
ax.tick_params(direction='in')
ax.set_aspect('equal')
odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

vmax = 15.
vmin = 0.
norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

ax.add_patch(odd)
ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Nunzio Losacco
Thank you so much for your help,

in fact, as `ax.set_aspect(‘equal’)` changes the bounding box at drawing time, others pointed out here that I should do:

```python
fig.canvas.draw()
```
before  getting the position of the axes. I assume that

 ```python 
ax.apply_aspect()
```
does the same.

I also found out that this does not work properly with the default MacOSX backend on a Mac,
with TkAgg produces a slight offset of the new axis wrt the desird position, but only in the interactive window,
with the qt5Agg backend it gives correct results both in the interactive window and in the output file.

Best,

Nunzio

On 20 Sep 2017, at 21:57, Jody Klymak <[hidden email]> wrote:

As pointed out by Eric Firing (here) you can also do:

ax.set_aspect(1.)
ax.apply_aspect()
pos = ax.get_position(original=False)

Cheers, Jody

On 20 Sep 2017, at 12:30, Jody Klymak wrote:


On 20 Sep 2017, at 11:32, Klymak Jody wrote:


Oops. Just realized you can also just do

Pos =ax._postion

To get the current position. Of course this could break because you are accessing a private variable.

oops again, no you can’t, you need to use the formula below. The reason is that apply_aspect doesn’t get called until the axes is drawn, so the new _position isn’t set until then.

Sorry, I should have checked before I wrote….

Cheers, Jody


Cheers. Jody

Sent from my iPhone

On Sep 20, 2017, at 11:07, Jody Klymak <[hidden email]> wrote:

Hi Nunzio,

The issue is that you call ax.set_aspect(‘equal’), and that changes the axes box. However, ax.get_position returns the frozen position, i.e. the old position. I don’t see a method to return the new position (and I wonder why get_position behaves this way).

As a work around, you can get the aspect-ratio changed position as:

figW, figH = fig.get_size_inches()
fig_aspect = figH / figW
newpos = pp.shrunk_to_aspect(ax.get_aspect() * ax.get_data_ratio(), pp, fig_aspect).anchored(ax.get_anchor(), pp))
which I appreciate is a bit of a pain….

Cheers, Jody

On 20 Sep 2017, at 7:06, Nunzio Losacco wrote:

Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
ax = axes[i]
ax.set_xlabel('distance [m]')
if i == 0:
ax.set_ylabel('depth [m]')
if i == 1:
ax.set_yticklabels([])
ax.invert_yaxis()
ax.tick_params(direction='in')
ax.set_aspect('equal')
odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

vmax = 15.
vmin = 0.
norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

ax.add_patch(odd)
ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users



_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Understanding axes position

Jody Klymak

This is something funky in append_axes and make_axes_locatable. If you instead just use subplots it behaves OK on OSX. Not sure if you have a good reason for using append_axes.

fig, axes = plt.subplots(1, 2, figsize=(6.3, 6.3))

ax1 = axes[0]
ax2 = axes[1]

Cheers, Jody

On 20 Sep 2017, at 14:23, Nunzio Losacco wrote:

Thank you so much for your help,

in fact, as `ax.set_aspect(‘equal’)` changes the bounding box at drawing time, others pointed out here that I should do:

```python
fig.canvas.draw()
```
before  getting the position of the axes. I assume that

 ```python 
ax.apply_aspect()
```
does the same.

I also found out that this does not work properly with the default MacOSX backend on a Mac,
with TkAgg produces a slight offset of the new axis wrt the desird position, but only in the interactive window,
with the qt5Agg backend it gives correct results both in the interactive window and in the output file.

Best,

Nunzio

On 20 Sep 2017, at 21:57, Jody Klymak <[hidden email]> wrote:

As pointed out by Eric Firing (here) you can also do:

ax.set_aspect(1.)
ax.apply_aspect()
pos = ax.get_position(original=False)

Cheers, Jody

On 20 Sep 2017, at 12:30, Jody Klymak wrote:


On 20 Sep 2017, at 11:32, Klymak Jody wrote:


Oops. Just realized you can also just do

Pos =ax._postion

To get the current position. Of course this could break because you are accessing a private variable.

oops again, no you can’t, you need to use the formula below. The reason is that apply_aspect doesn’t get called until the axes is drawn, so the new _position isn’t set until then.

Sorry, I should have checked before I wrote….

Cheers, Jody


Cheers. Jody

Sent from my iPhone

On Sep 20, 2017, at 11:07, Jody Klymak <[hidden email]> wrote:

Hi Nunzio,

The issue is that you call ax.set_aspect(‘equal’), and that changes the axes box. However, ax.get_position returns the frozen position, i.e. the old position. I don’t see a method to return the new position (and I wonder why get_position behaves this way).

As a work around, you can get the aspect-ratio changed position as:

figW, figH = fig.get_size_inches()
fig_aspect = figH / figW
newpos = pp.shrunk_to_aspect(ax.get_aspect() * ax.get_data_ratio(), pp, fig_aspect).anchored(ax.get_anchor(), pp))
which I appreciate is a bit of a pain….

Cheers, Jody

On 20 Sep 2017, at 7:06, Nunzio Losacco wrote:

Hi all,

what I’m trying to do here is having third plot with its base aligned with the others and with reduced height (the final aim is custom positioning a colorbar).
As you can see I’m getting the wrong position. What am I missing?

Thanks for any help

NL

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import numpy as np
from scipy.interpolate import griddata
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.pylab import cm
import matplotlib.colors as colors
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size

matplotlib.rcParams.update({'font.size': 8})

fig = plt.figure()
fig.set_size_inches(6.3,6.3)

ax1 = plt.subplot(111)
divider = make_axes_locatable(ax1)
ax2 = divider.append_axes('right', size='100%', pad=0.3)

axes = [ax1, ax2]
ltypes = ['dashed', 'solid']

xi = np.linspace(-18.125, 18.125, 11)
yi = np.linspace(0, 28, 9)
xv, yv = np.meshgrid(xi, yi)

xcOdd = 0.2
zcOdd = 0.725
xcEven = 0.6
zcEven = 0.725

maskRadius = 0.15

for i in range(2):
ax = axes[i]
ax.set_xlabel('distance [m]')
if i == 0:
ax.set_ylabel('depth [m]')
if i == 1:
ax.set_yticklabels([])
ax.invert_yaxis()
ax.tick_params(direction='in')
ax.set_aspect('equal')
odd = Circle((xcOdd, zcOdd), .15, linewidth=1.2, color='k', fill=False)
even = Circle((xcEven, zcEven), .15, linewidth=1.2, linestyle=ltypes[i], color='k', fill=False)

vmax = 15.
vmin = 0.
norm = matplotlib.colors.Normalize(vmin,vmax, clip=False)

color_map = matplotlib.colors.ListedColormap(plt.cm.Greys(np.linspace(0.25, 1, 5)), "name")

ax.add_patch(odd)
ax.add_patch(even)

pad = 0.03
width = 0.03

pos = ax2.get_position()

ax3 = fig.add_axes([pos.xmax + pad, pos.ymin, width, 0.7*(pos.ymax-pos.ymin) ])

plt.savefig('prova-vect-paper-test-2.eps', format='eps')

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users



_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users