0% found this document useful (0 votes)
548 views

Aspect Ratio in Subplots With Various Y-Axes: 3 Answers

Uploaded by

vaskore
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
548 views

Aspect Ratio in Subplots With Various Y-Axes: 3 Answers

Uploaded by

vaskore
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

Products Search… 1 1

Home
Aspect ratio in subplots with various y-axes Ask Question

PUBLIC Asked 7 years, 11 months ago Active 3 years ago Viewed 11k times

Stack Overflow
I would like the following code to produce 4 subplots of the same size with a common aspect ratio
Tags The Overflow Blog
between the size of x-axis and y-axis set by me. Referring to the below example, I would like all of
Users 9 the subplots look exactly like the first one (upper left). What is wrong right now is that the size of Podcast 307: Owning the code, from
the y-axis is correlated with its largest value. That is the behaviour I want to avoid. integration to delivery
FIND A JOB
Building momentum in our transition to a
Jobs
import matplotlib.pyplot as plt product led SaaS company
Companies 5 import numpy as np
Featured on Meta
def main():
TEAMS What’s this?
fig = plt.figure(1, [5.5, 3]) Opt-in alpha test for a new Stacks editor
Free 30 Day Trial
for i in range(1,5):
fig.add_subplot(221+i-1, adjustable='box', aspect=1) 2020: a year in moderation
plt.plot(np.arange(0,(i)*4,i))
Hot Meta Posts
plt.show()

if __name__ == "__main__": 13 Is it valid for a diamond moderator to use


main() his powers to override the closing…

7 Was this question correctly closed as


“needing of details and clarity”?
Surprisingly, matplotlib produces the right thing by default (picture below):
21 Ask the owner of a post whether they
agree with an edit
import matplotlib.pyplot as plt
import numpy as np

def main(): Love this site?


fig = plt.figure(1, [5.5, 3])
for i in range(1,5):
Get the weekly newsletter! In it, you'll get:
fig.add_subplot(221+i-1)
plt.plot(np.arange(0,(i)*4,i)) The week's top questions and answers
plt.show()
Important community announcements
Questions that need answers
I just want to add to this an ability to control the aspect ratio between lengths of x and y-axes.
Sign up for the digest

see an example newsletter

Linked

1 matplotlib/python: force axes to same


length for multiple subplots

15 new pythonic style for shared axes square


subplots in matplotlib?

9 matplotlib axes.set_aspect('equal') doesn't


behave like expected

1 Aspect ratio of a plot

1 Extent and aspect; square pixels in an


image with shared axis in matplotlib

Related

482 How do I resize an image using PIL and


python matplotlib
maintain its aspect ratio?

27 matplotlib - subplots with fixed aspect ratio


Share Edit Follow edited Oct 23 '17 at 20:15 asked Feb 16 '13 at 4:47
BartoszKP user2077647 351 Improve subplot size/spacing with many
31.5k 13 88 122 93 1 1 5 subplots in matplotlib

263 Matplotlib different size subplots


add a comment
358 How do I change the figure size with
subplots?
3 Answers Active Oldest Votes
0 Precise control over subplot locations in
matplotlib
I can't quite tell what you want from your question. 1 the graphs of the two projectiles does not
work properly when complementary
10 Do you want all of the plots to have the same data limits? angles(eg 30 and 60) are passes to
xy_plot1 and xyplot2 function
If so, use shared axes (I'm using subplots here, but you can avoid it if you want to stick to
matlab-style code): Hot Network Questions
Prolonging a siege indefinitely by tunneling
import matplotlib.pyplot as plt
didn't hear back after a postdoc interview, can I set
import numpy as np
a deadline for a response?

fig, axes = plt.subplots(nrows=2, ncols=2, sharey=True, sharex=True) What is the minimum amount of votes needed in
for i, ax in enumerate(axes.flat, start=1): both Chambers of Congress to send an Admission
ax.set(aspect=1) to the Union resolution to the President?
ax.plot(np.arange(0, i * 4, i)) Could double jeopardy protect a murderer who
bribed the judge and jury to be declared not guilty?
plt.show()
Calculating the Angular Momentum of a planet

The author primary signature's timestamp found a


chain building issue: UntrustedRoot: self signed
certificate in certificate chain

How to find SMD Resistor + Capacitor Value and


Correct Size

Intuitively, what actually is the cause of


resonance?

Sub panel install issue

Why isn't the constitutionality of Trump's 2nd


impeachment decided by the supreme court?

Why don't flights fly towards their landing


approach path sooner?

Implement a zipwith function

Is it offensive to kill my gay character at the end of


my book?

Can the Wish spell change my spell list?

Identifying rows and columns of a matrix that


satisfy a specific feature

Child travelling abroad and money

A disagreement with coauthor/boss about funding

Cannot program two arduinos at the same time


because they both use the same COM port

Frame dropout cracked, what can I do? (Allied Alfa


Disc / carbon)

Why can’t I turn “fast-paced” into a quality noun by


If you want them all to share their axes limits, but to have adjustable='box' (i.e. non-square adding the “‑ness” suffix?
axes boundaries), use adjustable='box-forced' : Time raids from an impoverished future, where do
the resources go? How to balance the books?

import matplotlib.pyplot as plt How to prevent pictures from being downloaded


import numpy as np by right-clicking on them or Inspecting the web
page?
fig, axes = plt.subplots(nrows=2, ncols=2, sharey=True, sharex=True) Can you use Wild Shape to meld a Bag of Holding
for i, ax in enumerate(axes.flat, start=1): into your Wild Shape form while creatures are
ax.set(aspect=1, adjustable='box-forced', xticks=range(i)) inside the Bag of Holding?
ax.plot(np.arange(0, i * 4, i))
Why can I not assemble conduit around cable, but
must pull it after assembly?
plt.show()
Question feed

Edit: Sorry, I'm still a bit confused. Do you want something like this?

import matplotlib.pyplot as plt


import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2)


for i, ax in enumerate(axes.flat, start=1):
ax.set(adjustable='datalim', aspect=1)
ax.plot(np.arange(0, i * 4, i))

plt.show()

Okay, I think I finally understand your question. We both meant entirely different things by "aspect
ratio".

In matplotlib, the aspect ratio of the plot refers to the relative scales of the data limits. In other
words, if the aspect ratio of the plot is 1, a line with a slope of one will appear at 45 degrees. You
were assuming that the aspect ratio applied to the outline of the axes and not the data plotted on
the axes.

You just want the outline of the subplots to be square. (In which case, they all have different aspect
ratios, as defined by matplotlib.)

In that case, you need a square figure. (There are other ways, but just making a square figure is far
simpler. Matplotlib axes fill up a space that is proportional to the size of the figure they're in.)

import matplotlib.pyplot as plt


import numpy as np

# The key here is the figsize (it needs to be square). The position and size of
# axes in matplotlib are defined relative to the size of the figure.
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8,8))

for i, ax in enumerate(axes.flat, start=1):


ax.plot(np.arange(0, i * 4, i))

# By default, subplots leave a bit of room for tick labels on the left.
# We'll remove it so that the axes are perfectly square.
fig.subplots_adjust(left=0.1)

plt.show()

Share Edit Follow edited Feb 18 '13 at 4:36 answered Feb 16 '13 at 15:34
Joe Kington
231k 60 543 442

Hi Joe! Thanks for the attention to my question. I am sorry for the confusion. Neither of your 2 options
provides exactly what I am looking for. The first option is the closest though. It would be perfect if each
one of subplots had its own limit of y-axis. That is what matplotlib does automatically. For instance, the
following: (in the next message) produces the look that I want, but I would also like to control the aspect
ratio of those subplots (one aspect ratio for all of them) – user2077647 Feb 16 '13 at 19:38

code: import matplotlib.pyplot as plt import numpy as np def main(): fig = plt.figure(1, [5.5, 3]) for i in
range(1,5): fig.add_subplot(221+i-1) plt.plot(np.arange(0,(i)*4,i)) plt.show() – user2077647 Feb 16 '13 at
19:41

I have added the picture this code produces in my original question – user2077647 Feb 16 '13 at 19:45

Hi Joe, almost there! This is perfect except I would like all of the suplots have the x-axes limits to be from
0 to 3. That picture I included in the original question is everything I want but with wrong aspect ratio
between axes. So right now it is something like 1/2 but I am looking for 1/1. – user2077647 Feb 17 '13 at
19:18

Sorry, I'm still confused... The aspect ratio can't be constant if neither the limits or size of the axes change.
You seem to be asking for plots that are the exact same size, have the same aspect ratio, the same x-axis
limits, but different y-axis limits. That's impossible, by definition. I think I'm just misunderstanding your
question... – Joe Kington Feb 17 '13 at 23:58

show 5 more comments

Combing the answer of Joe Kington with new pythonic style for shared axes square subplots in
matplotlib? and another post that I am afraid I cannot find it again, I made a code for precisely
2 setting the ratio of the box to a given value.

Let desired_box_ratioN indicate the desired ratio between y and x sides of the box.
temp_inverse_axis_ratioN is the ratio between x and y sides of the current plot; since 'aspect' is the
ratio between y and x scale (and not axes), we need to set aspect to desired_box_ratioN *
temp_inverse_axis_ratioN.

import matplotlib.pyplot as plt


import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2)

desired_box_ratioN = 1
for i, ax in enumerate(axes.flat, start=1):
ax.plot(np.arange(0, i * 4, i))
temp_inverse_axis_ratioN = abs( (ax.get_xlim()[1] - ax.get_xlim()[0])/(ax.get_ylim()[1] - ax.get_ylim()[0]) )
ax.set(aspect = desired_box_ratioN * temp_inverse_axis_ratioN, adjustable='box-forced')

plt.show()

Share Edit Follow edited May 23 '17 at 10:28 answered Aug 4 '14 at 14:47
Community ♦ Igor Fobia
1 1 649 8 20

add a comment

The theory
1 Different coordinate systems exists in matplotlib. The differences between different coordinate
systems can really confuse a lot of people. What the OP want is aspect ratio in display coordinate
but ax.set_aspect() is setting the aspect ratio in data coordinate. Their relationship can be
formulated as:

aspect = 1.0/dataRatio*dispRatio

where, aspect is the argument to use in set_aspect method, dataRatio is aspect ratio in data
coordinate and dispRatio is your desired aspect ratio in display coordinate.

The practice
There is a get_data_ratio method which we can use to make our code more concise. A work
code snippet is shown below:

import matplotlib.pyplot as plt


import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2)

dispRatio = 0.5
for i, ax in enumerate(axes.flat, start=1):
ax.plot(np.arange(0, i * 4, i))
ax.set(aspect=1.0/ax.get_data_ratio()*dispRatio, adjustable='box-forced')

plt.show()

I have also written a detailed post about all this stuff here.

Share Edit Follow edited Jan 8 '18 at 2:13 answered Jan 8 '18 at 2:02
jdhao
11.8k 7 74 132

I have tried to follow your tutorial, which is very clear, however, it does not work when the y-axis has a log
scale, any ideas on widening the x-axis while keeping y-axis on log scale? – seanysull Feb 19 '19 at 15:05

Sorry, I am not sure. Maybe you can open a new question here on Stack Overflow based on that post. –
jdhao Feb 19 '19 at 16:47

add a comment

Your Answer

Links Images Styling/Headers Lists Blockquotes Code HTML Tables Advanced help

Post Your Answer

Not the answer you're looking for? Browse other questions tagged python matplotlib or ask your own
question.

STACK OVERFLOW PRODUCTS COMPANY STACK EXCHANGE Blog Facebook Twitter LinkedIn Instagram
NETWORK
Questions Teams About
Technology
Jobs Talent Press
Life / Arts
Developer Jobs Directory Advertising Work Here
Culture / Recreation
Salary Calculator Enterprise Legal
Science
Help Privacy Policy
Other
Mobile Terms of Service
site design / logo © 2021 Stack Exchange Inc; user contributions
Disable Responsiveness Contact Us licensed under cc by-sa. rev 2021.1.27.38425

You might also like