How to set aspect ratio in matplotlib?

I am trying to make a square graph (using imshow), i.e. aspect ratio 1: 1, but I can’t. None of these works:

import matplotlib.pyplot as plt ax = fig.add_subplot(111,aspect='equal') ax = fig.add_subplot(111,aspect=1.0) ax.set_aspect('equal') plt.axes().set_aspect('equal') 

It seems that the calls are simply ignored (a problem that I often encounter with matplotlib).

+96
python matplotlib
Nov 01 '11 at 11:27
source share
5 answers

Third time charm. I assume this is a mistake, and Eugene's answer suggests that it is fixed in the latest version. I have version 0.99.1.1 and I created the following solution:

 import matplotlib.pyplot as plt import numpy as np def forceAspect(ax,aspect=1): im = ax.get_images() extent = im[0].get_extent() ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect) data = np.random.rand(10,20) fig = plt.figure() ax = fig.add_subplot(111) ax.imshow(data) ax.set_xlabel('xlabel') ax.set_aspect(2) fig.savefig('equal.png') ax.set_aspect('auto') fig.savefig('auto.png') forceAspect(ax,aspect=1) fig.savefig('force.png') 

This is "force.png": enter image description here

Below are my unsuccessful, but hopefully informative attempts.

Second answer:

My "original answer" below is redundant as it does something similar to axes.set_aspect() . I think you want to use axes.set_aspect('auto') . I don’t understand why this is so, but for me I get a square graph of the image, for example, this script:

 import matplotlib.pyplot as plt import numpy as np data = np.random.rand(10,20) fig = plt.figure() ax = fig.add_subplot(111) ax.imshow(data) ax.set_aspect('equal') fig.savefig('equal.png') ax.set_aspect('auto') fig.savefig('auto.png') 

Produces graphics images with an equal aspect ratio: enter image description here and one with the format "auto": enter image description here

The code below in the "original answer" provides a starting point for an explicitly controlled aspect ratio, but it seems to be ignored after calling imshow.

Original answer:

Here is an example of a procedure that will adjust the subtask settings to get the desired aspect ratio:

 import matplotlib.pyplot as plt def adjustFigAspect(fig,aspect=1): ''' Adjust the subplot parameters so that the figure has the correct aspect ratio. ''' xsize,ysize = fig.get_size_inches() minsize = min(xsize,ysize) xlim = .4*minsize/xsize ylim = .4*minsize/ysize if aspect < 1: xlim *= aspect else: ylim /= aspect fig.subplots_adjust(left=.5-xlim, right=.5+xlim, bottom=.5-ylim, top=.5+ylim) fig = plt.figure() adjustFigAspect(fig,aspect=.5) ax = fig.add_subplot(111) ax.plot(range(10),range(10)) fig.savefig('axAspect.png') 

The result is this figure: enter image description here

I can assume that if you have several subplots in the figure, you would like to include the number of subplots y and x as keyword parameters (default is 1 by default) in the provided procedure. Then, using these numbers and the hspace and wspace , you can make all the subheadings have the correct aspect ratio.

+67
Nov 01 2018-11-11T00:
source share

What is the version of matplotlib you are using? I recently had to upgrade to 1.1.0 , and with it add_subplot(111,aspect='equal') works for me.

+19
Nov 01 '11 at 16:18
source share

you should try with figaspect. It works for me. From the docs:

Create a shape with the specified aspect ratio. If arg is a number, use this aspect ratio. > If arg is an array, then the fig will determine the width and height of the figure, which will correspond to the array while maintaining the aspect ratio. The width of the picture, the height in inches is back. Remember to create axes with equal and height, for example

Usage example:

  # make a figure twice as tall as it is wide w, h = figaspect(2.) fig = Figure(figsize=(w,h)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax.imshow(A, **kwargs) # make a figure with the proper aspect for an array A = rand(5,3) w, h = figaspect(A) fig = Figure(figsize=(w,h)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax.imshow(A, **kwargs) 

Edit: I'm not sure what you are looking for. The above code changes the canvas (chart size). If you want to resize the matplotlib window, in the figure, use:

 In [68]: f = figure(figsize=(5,1)) 

this creates a 5x1 (wxh) window.

+3
Nov 01 '11 at 12:35
source share

This answer is based on Yann's answer. It will set the aspect ratio for linear or logarithmic graphs. I used the additional information from https://stackoverflow.com/a/3126268/8 to check if the axes are scaled.

 def forceAspect(ax,aspect=1): #aspect is width/height scale_str = ax.get_yaxis().get_scale() xmin,xmax = ax.get_xlim() ymin,ymax = ax.get_ylim() if scale_str=='linear': asp = abs((xmax-xmin)/(ymax-ymin))/aspect elif scale_str=='log': asp = abs((scipy.log(xmax)-scipy.log(xmin))/(scipy.log(ymax)-scipy.log(ymin)))/aspect ax.set_aspect(asp) 

Obviously you can use whatever version of log you want, I used scipy , but numpy or math should be fine.

+2
Jul 15 '17 at 22:23
source share

After many years of success with the answers above, I found that this no longer works - but I found a working solution for sites on

https://jdhao.imtqy.com/2017/06/03/change-aspect-ratio-in-mpl

Of course, with full respect to the author above (which may post here), the relevant lines are:

 ratio = 1.0 xleft, xright = ax.get_xlim() ybottom, ytop = ax.get_ylim() ax.set_aspect(abs((xright-xleft)/(ybottom-ytop))*ratio) 

The link also contains a crystal clear explanation of the various coordinate systems used by matplotlib.

Thanks for all the great answers I received - especially @Yann, who will be the winner.

0
Jul 29 '19 at 7:45
source share



All Articles