Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib - Keep aspect ratio when using multiple axes

How can I keep the aspect ratio of a plot when using two x axes? The code below works well showing an image of aspect ratio 25/111.

import numpy as np
import matplotlib.pyplot as plt

data = np.ones((25, 111))
specFig, specAx = plt.subplots()
specAx.set_xlim([0, data.shape[1]])

#newax = specAx.twiny()
#newax.set_xlim([0, data.shape[1]])

specAx.imshow(data, origin="lower")
plt.show()

However, when uncommenting the lines, it becomes a rather quadratic image whose second x-axis is showing values from 0 to 111 whereas the first x axis only shows a clipping of some 25 values.

like image 338
limes Avatar asked Mar 26 '26 06:03

limes


1 Answers

It's strange, I cannot get the axes to look correct with axis('tight'), axis('scaled'), etc, specAx.set_aspect(aspect, adjustable='box'), turning off autoscale or anything. I've had similar problems with dual axis in matplotlib and as a workaround used matplotlib's parasiteaxis, which for your case would be,

import numpy as np
import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA

data = np.ones((25, 111))

specFig = plt.figure()
specAx = host_subplot(111, axes_class=AA.Axes)

specAx.set_xlim([0, data.shape[1]])
specAx.imshow(data, origin="lower")

#Add parasite axis
newax = specAx.get_grid_helper().new_fixed_axis
specAx.axis["top"] = newax(loc="top", axes=specAx)

plt.show()

EDIT: If you need to adjust the top axis, the previous solution is probably not ideal (the top axis is not an axis object). I've managed to get it working using the box-forced keyword in set the aspect ratio as follows:

import numpy as np
import matplotlib.pyplot as plt

data = np.ones((25, 111))
specFig, specAx = plt.subplots()
specAx.set_xlim([0, data.shape[1]])

newax = specAx.twiny()
newax.set_xlim([0, data.shape[1]])

specAx.imshow(data, origin="lower")
specAx.set_aspect('equal', 'box-forced')
newax.set_aspect('equal', 'box-forced')
plt.show()

You should then be able to adjust ticks, etc.

like image 58
Ed Smith Avatar answered Mar 28 '26 19:03

Ed Smith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!