Reputation: 792
I've been trying to build a layout that looks like an example from the matplotlib gallery, with some modifications:
xlim != ylim
twiny()
setupThe cited example seems to hard code in the positions of the axes, when I'd like this to be done dynamically as the x and y limits in the central axes may change.
I've tried different approaches, but I'll first walk through a method with add_sublot()
.
The central axes can be made with something like (anticipating using an AxisDivider
to add the top axes, thus the 121):
from matplotlib.pyplot import *
fig = gcf()
ax_c = fig.add_subplot(121,aspect='equal',xlim=[0,2],ylim=[0,0.5])
draw()
yielding the expected results. (This is my first time using StackExchange so I don't yet have the 10 reputation to post images, or more than two links.) Fine. But when I add the add the second subplot, like:
ax_r = fig.add_subplot(122,sharey=ax_c,xlim=[0,4])
draw()
the aspect ratio is destroyed, as are the originally set x limits.
Results using a GridSpec
seem to be identical, and there's another implementation of the given example with AxesDivider
, but I've determined that I cannot use an AxesDivider
with the help of append_axes()
as I would also like to generate a twiny()
axes on the right, and given the way that twiny()
and AxesGrid
are implemented, the twiny()
axes ends up spanning the entire figure.
fig.clf()
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
ax_c = fig.add_subplot(111,aspect='equal',xlim=[0,2],ylim=[0,0.5])
divider = make_axes_locatable(ax_c)
ax_r = divider.append_axes("right", size=1.3, pad=0.1, sharey=ax_c)
ax_rty = ax_r.twiny()
draw()
I presume the colorbar, the desired top axes spanning the width of the the central axes, can be implemented with the make_axes_locatable()
method. I've also tried an AxesGrid
, which handles the color bar nicely, but this construction is not amenable to different axis scales and didn't seem to work for the central and right axes combination.
Upvotes: 1
Views: 499
Reputation: 792
This is a slightly ugly way to answer my own question, I hacked the following code from the first example I referenced. It's definitely something I'd like to handle with higher-level helpers, so other shorter/cleaner answers are welcome.
import numpy as np
import matplotlib.pyplot as plt
xlim = (-60.,60.)
ylim = (-110.,110.)
axes_pad = 0.02
cbar_height = 0.025
h_pad = 0.1
v_pad = 0.1
fig_w = 7.
fig_h = 6.
height = 1-axes_pad-cbar_height-2*v_pad
width = np.abs((xlim[1]-xlim[0])/(ylim[1]-ylim[0]))*height*fig_h/fig_w # ensure equal aspect
bottom_h = v_pad+height+axes_pad
left_h = h_pad+width+axes_pad
rect_c = [h_pad, v_pad, width, height]
rect_cbar = [h_pad, bottom_h, width, cbar_height]
rect_r = [left_h, v_pad, 1-axes_pad-width-2*h_pad, height]
fig = plt.figure(1, figsize=(fig_w,fig_h))
ax_c = plt.axes(rect_c)
ax_cbar = plt.axes(rect_cbar)
ax_r = plt.axes(rect_r)
ax_c.set_xlim(xlim)
ax_c.set_ylim(ylim)
ax_r.set_ylim(ylim)
ax_rty = ax_r.twiny()
ax_rty.set_xlim((-100,0)) # determined dynamically later
ax_r.set_xlim((0,0.5)) # determined dynamically later
plt.savefig('skeleton.pdf',bbox_inches='tight')
Upvotes: 1