1

There are several related questions (here, here, and here), but the suggested solutions don't work in my case.

I'm creating subplots iteratively, so I don't know ahead of time the width of each one (it gets calculated AFTER plt.subplots() is called), which means I can't set the size of each subplot when I initially create them. I would like to set the size of the subplot x axis after it has already been created.

Imagine something like:

items = [A,B,C]  #this could have any number of items in it
f,ax = plt.subplots(len(items),1, figsize=(10,10)) #figsize is arbitrary and could be anything

for i in range(len(items)):
    #calculate x and y data for current item
    #calculate width of x axis for current item
    plt.sca(ax[i])
    cax = plt.gca()
    cax.plot(x,y)
    #here is where I would like to set the x axis size
    #something like cax.set_xlim(), but for the size, not the limit

Note 1: The units don't matter, but the relative size does, so it could be size in pixels, or centimeters, or even a ratio calculated based on the relative widths.

Note 2: The width of the x axis is NOT related in this case to the x limit, so I can't just set the x limit and expect the axis to scale correctly.

Also, I'm trying to keep this code short, since it's to be shared with people unfamiliar with Python, so if the only solution involves adding a bunch of lines, it's not worth it and I'll live with incorrectly scaled axes. This is an aesthetic preference but not a requirement. Thanks!

EDIT: Here's what I'm aiming for desired subplots

5
  • Are you talking about the relative or absolute size of the subplots? Commented Nov 28, 2018 at 15:34
  • Doesn't matter - what I want is for them to be scaled appropriately relative to each other (they're geologic cross-sections, so the x axis size is based on the distance between point A and point B of the cross-section on a map), but if the easiest way to do that is to fix an absolute size for each one, that works too. Commented Nov 29, 2018 at 8:57
  • 1
    Relavtive size is easy as shown in the answer by @Felix. Commented Nov 29, 2018 at 13:16
  • Did you see my response? That approach seems to require knowing what relative size each subplot should be ahead of time. My problem is that I don't know what the size should be until AFTER I'm already in the loop. Am I misunderstanding something in the answer? Commented Nov 29, 2018 at 13:38
  • 2
    The answer sets the height_ratios after the plotting. So by then you will know what they need to be. Commented Nov 29, 2018 at 13:41

2 Answers 2

1

You can create a new GridSpec specifying the height_ratios and then updating each axs position:

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

# create figure
f, ax = plt.subplots(3, 1, figsize=(10,10))

# plot some data
ax[0].plot([1, 2, 3])
ax[1].plot([1, 0, 1])
ax[2].plot([1, 2, 20])

# adjust subplot sizes
gs = GridSpec(3, 1, height_ratios=[5, 2, 1])
for i in range(3):
    ax[i].set_position(gs[i].get_position(f))

plt.show()

I asked a similar question before here. The use case was slightly different, but it might still be helpful.

Sign up to request clarification or add additional context in comments.

7 Comments

The problem with this approach (if I understand correctly) is that you set the gridspec ratios BEFORE the loop, whereas I don't know the ratios until I'm inside the loop, so I need to be able to modify the axes after they're created.
That's exactly what you can do using the code above. Your loop would go below the "plot some data" block. Once its finished and you know the ratios, create the Gridspec and update the positions/sizes of the existing axes (see the "adjust subplot sizes" block).
Ah got it sorry - I thought gridspec needed to be set before plotting. So there are two loops, one to plot each subplot, and one to update them afterwards. That works great! Thanks!
Yeah it took me a while to get that, too. You're welcome ;-)
Ah actually - a problem. GridSpec works great to change the height ratios if you have one column, but it doesn't work to change the width ratios if the subplots are all in the same column - I think it can only change the width ratios if each subplot is in its own column. :(
|
1

Surely now you got the answer or this problem is deprecated but if someone else is searching, I solved this problem using "Bbox". The idea is something like this:

from matplotlib.transforms import Bbox

fig, ax = plt.subplots(3,1, figsize = (11,15))
ax[0].set_position(Bbox([[0.125, 0.6579411764705883], [0.745, 0.88]]))
ax[2].set_position(Bbox([[0.125, 0.125], [0.745, 0.34705882352941175]]))

For more information, check https://matplotlib.org/api/transformations.html#matplotlib.transforms.Bbox

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.