215

How do I create a plot where the scales of x-axis and y-axis are the same?

This equal ratio should be maintained even if I change the window size. Currently, my graph scales together with the window size.

I tried:

plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.axis('equal')
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Sibbs Gambling
  • 19,274
  • 42
  • 103
  • 174
  • for 3d, you have to do a little bit extra work: http://stackoverflow.com/questions/13685386/matplotlib-equal-unit-length-with-equal-aspect-ratio-z-axis-is-not-equal-to – Trevor Boyd Smith Oct 21 '16 at 16:07

5 Answers5

293

Use Axes.set_aspect in the following manner:

from matplotlib import pyplot as plt
plt.plot(range(5))
plt.xlim(-3, 3)
plt.ylim(-3, 3)
ax = plt.gca()
ax.set_aspect('equal', adjustable='box')
plt.draw()
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • 5
    Awesome! It indeed works like charm. Could you please tell me what `plt.plot(range(5))` and `plt.gca().set_aspect('equal', adjustable='box')` do, if you don't mind? Also, I notice that even if I don't have `plt.draw()`, the plot will still show up. Then what is the use of it? – Sibbs Gambling Aug 02 '13 at 01:43
  • the `plot` is just have something to show. For the `set_aspect` read the documentation link. The `draw` is just to make sure it gets rendered. – tacaswell Aug 02 '13 at 01:49
  • Sorry but I am asking about the range(5) thing inside plot(). What does the range(5) do? – Sibbs Gambling Aug 02 '13 at 02:00
  • ah, `range(5)` returns `[0, 1, 2, 3, 4]` See: http://docs.python.org/2/library/functions.html#range – tacaswell Aug 02 '13 at 02:03
  • yah, I know it returns that, but then why do I feed the list to plot()? – Sibbs Gambling Aug 02 '13 at 02:06
  • 1
    to have some fake data to plot (it should have plotted a straight line). – tacaswell Aug 02 '13 at 02:08
  • 1
    @perfectionm1ng no worries, took me a while to figure out what you were asking. – tacaswell Aug 02 '13 at 02:40
  • I don't see the need to set both limits to the same ranges, this can result in different scales, especially when most plots are not square shaped. – Mehdi Apr 11 '17 at 12:23
  • 1
    Is there a way to get this done without having to specify exactly the limits? I would have expected there to be a simple command to get a square plot with the same scale and ticks for both axis. Thanks – Confounded Feb 25 '20 at 10:34
  • @Confounded: As stated below, if you don't want to give any limits you can just use `plt.axis('square')` – Isi Aug 03 '20 at 14:55
  • This is really great, thank you. For a specific subplot you can also do `ax.set_aspect('equal', adjustable='box')` – ofekp Nov 08 '21 at 21:09
100
plt.axis('scaled')

works well for me.

Georgy
  • 12,464
  • 7
  • 65
  • 73
myx
  • 1,161
  • 1
  • 10
  • 17
68

See the documentation on plt.axis(). This:

plt.axis('equal')

doesn't work because it changes the limits of the axis to make circles appear circular. What you want is:

plt.axis('square')

This creates a square plot with equal axes.

Adam Stewart
  • 2,001
  • 1
  • 16
  • 16
22

Try something like:

import pylab as p
p.plot(x,y)
p.axis('equal')
p.show()
Dman2
  • 700
  • 4
  • 10
  • This works on my system, perhaps you could show a portion of the code you are working on? Might be able to help work out the issue quicker. – Dman2 Aug 01 '13 at 15:27
  • This does NOT work in general. The axes are equal, but the plot is not square, unless the plotting window is also square. Tested with Matplotlib 2.0 – divenex Apr 25 '17 at 21:19
  • 1
    `P.axis('equal')` seems to be like `P.gca().set_aspect('equal', adjustable='datalim')`. While if `adjustable='box'`, then the plot becomes square. – Evgeni Sergeev Jan 03 '18 at 09:22
  • 1
    I definitely do *not* get a square box out of this. – Peter Drake Apr 17 '19 at 15:58
  • 1
    pylab is deprecated – eric Jul 29 '20 at 13:46
  • If you want to also have the grid square, in addition to aspect as mentioned in the other answers, see https://stackoverflow.com/a/65049909/55935 – Giovanni Funchal Nov 29 '20 at 14:31
-1

you can stretch the plot to square using this :

fig = plt.figure(figsize=(1, 1))
rzb
  • 19
  • 8