proplot-dev / proplot

🎨 A succinct matplotlib wrapper for making beautiful, publication-quality graphics
https://proplot.readthedocs.io
MIT License
1.07k stars 96 forks source link

Inconsistent width of axes #395

Open Yefee opened 1 year ago

Yefee commented 1 year ago

Description

The width of axes are inconsistent.

Steps to reproduce

layout = [[1, 1, 2, 2, 3, 3],
          [4, 4, 4, 5, 5, 5]]

fig, axs = pplt.subplots(layout, sharey=False, proj={4:'merc'}, proj_kw={'lon_0': 180},
                         hratios=[1, 1], refnum=4, wratios= [1, 1, 1, 1, 1, 1], journal='nat2')
axs.format(land=True, landcolor='k')

axs[0].plot(np.arange(10))
axs[1].plot(np.arange(10))
axs[2].plot(np.arange(10))

Expected behavior: [What you expected to happen] The axes in the top row, axs[0:3], shall have the same width. Actual behavior: [What actually happened]

axs[1] is wider than the other two.

CleanShot 2022-10-02 at 22 51 40@2x

Proplot version

Matplotlib 3.4.3 Prophet 0.9.5

zxdawn commented 1 year ago

I suppose the problem is caused by refnum. The code below works well:

fig, axs = pplt.subplots(layout, sharey=False, proj={4:'merc'}, proj_kw={'lon_0': 180})
image
lukelbd commented 1 year ago

Thanks zxdawn for the example -- that is a little better, but I guess another issue is that there is now empty space around the map. Turns out enforcing equal spacing between gridspec slots by passing wequal=True to pplt.subplots() results in both equal-width subplots in both rows and zero excess space around the projection:

layout = [[1, 1, 2, 2, 3, 3],
          [4, 4, 4, 5, 5, 5]]

fig, axs = pplt.subplots(layout, sharey=False, proj={4:'merc'}, proj_kw={'lon_0': 180},
                         hratios=[1, 1], refnum=4, wratios= [1, 1, 1, 1, 1, 1], journal='nat2', wequal=True)
axs.format(land=True, landcolor='k')

axs[0].plot(np.arange(10))
axs[1].plot(np.arange(10))
axs[2].plot(np.arange(10))

iTerm2 ImWtwV tmpx3og460g

The answer here is a little complicated. The "ratrios" in your wratios argument actually refer to gridspec slots, not wspace/hspace spaces in-between the slots. So, while the gridspec slot ratios are all still 1:1 in your example, proplot adjusted the "tight layout" spacing to zero between the first 2 gridspec columns and last 2 gridspec columns (where there are no subplot edges, so no need for space)... resulting in unequally sized axes, since they span different gridspec spaces.

Instead of wequal=True, you can also manually set wspace to some scalar value, or disable the tight layout algorithm with tight=False, and that will solve this issue too.

lukelbd commented 1 year ago

I think I'll keep this open actually. IIRC I've run into something like this in my own research.

In this sort of case where subplots span across a gridspec space (or maybe more broadly, when there is no subplot-subplot interface?) it would probably make more sense to set that space to the average of the other spaces in the gridspec by default, rather than just setting that space to zero. That should result in the intuitive result you were expecting -- where a symmetrical number of subplot identifiers in your array result in symmetrical widths of the resulting subplots.