Axes class - set explicitly size (width/height) of axes in given units
The axes size is determined by the figure size and the figure spacings, which can be set using figure.subplots_adjust()
. In reverse this means that you can set the axes size by setting the figure size taking into acount the figure spacings:
import matplotlib.pyplot as plt
def set_size(w,h, ax=None):
""" w, h: width, height in inches """
if not ax: ax=plt.gca()
l = ax.figure.subplotpars.left
r = ax.figure.subplotpars.right
t = ax.figure.subplotpars.top
b = ax.figure.subplotpars.bottom
figw = float(w)/(r-l)
figh = float(h)/(t-b)
ax.figure.set_size_inches(figw, figh)
fig, ax=plt.subplots()
ax.plot([1,3,2])
set_size(5,5)
plt.show()
determine matplotlib axis size in pixels
This gives the width and height in inches.
bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width, height = bbox.width, bbox.height
That probably suffices for your purpose, but to get pixels, you can multiply by fig.dpi
:
width *= fig.dpi
height *= fig.dpi
For example,
import matplotlib.pyplot as plt
def get_ax_size(ax):
bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width, height = bbox.width, bbox.height
width *= fig.dpi
height *= fig.dpi
return width, height
fig, ax = plt.subplots()
print(get_ax_size(ax))
#(496.0, 384.00000000000006)
ax2 = plt.axes([0.3, 0.3, 0.7, 0.7])
print(get_ax_size(ax2))
# (448.0, 336.0)
To make an image of exactly that figure size, you have to remove whitespace between the figure and the axis:
import numpy as np
import matplotlib.pyplot as plt
def get_ax_size(ax):
bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width, height = bbox.width, bbox.height
width *= fig.dpi
height *= fig.dpi
return width, height
data = np.arange(9).reshape((3, 3))
fig = plt.figure(figsize=(8,6), dpi=80)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(data, aspect='equal')
print(get_ax_size(ax))
# (640.0, 480.0)
plt.savefig('/tmp/test.png', dpi=80)
% identify /tmp/test.png
/tmp/test.png PNG 640x480 640x480+0+0 8-bit DirectClass 50.5KB 0.020u 0:00.020
display image with maximum width keeping an equal ratio
Found with a reading of Axes class - set explicitly size (width/height) of axes in given units
and the use of
set_adjustable('datalim')
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(nrows=2, figsize=(8,8))
img = ax[0].imshow(np.random.random((10,10)), aspect='equal')
ax[0].set_adjustable('datalim')
line = ax[1].plot([12,34],[45,78])
Same width and height axis in matplotlib for every plot
Thanks @Jody. As your suggestion, I update my code as following. This work for me
max_range = np.array([x2-x1, y2-y1]).max()/2.0
axis.set_xlim((x1+x2)*0.5-max_range, (x1+x2)*0.5+max_range)
axis.set_ylim((y1+y2)*0.5-max_range, (y1+y2)*0.5+max_range)
Matplotlib set subplot axis size iteratively
You can create a new GridSpec
specifying the height_ratios
and then updating each ax
s 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.
How do I equalize the scales of the x-axis and y-axis?
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()
Specify axis-data margin in matplotlib
We can slightly adapt the function from Axes class - set explicitly size (width/height) of axes in given units
to add a line setting the axes margins.
import matplotlib.pyplot as plt
def set_size(w,h, ax=None, marg=(0.1, 0.1)):
""" w, h: width, height in inches """
if not ax: ax=plt.gca()
l = ax.figure.subplotpars.left
r = ax.figure.subplotpars.right
t = ax.figure.subplotpars.top
b = ax.figure.subplotpars.bottom
figw = float(w)/(r-l)
figh = float(h)/(t-b)
ax.figure.set_size_inches(figw, figh)
ax.margins(x=marg[0]/w, y=marg[1]/h)
And call it with
set_size(width, height, marg=(xmargin, ymargin))
where xmargin, ymargin
are the margins in inches.
Aspect ratio (vs. size and position) of inset_axis of axes_divider host axes
As long as the figure is not drawn, the divider axes do not yet know their size. Therefore their bbox is just as large as the parent bbox. The inset_axes are therefore calculated in terms of the main axes size.
This is actually a more or less general rule: If you want to use .get_window_extent()
on an artist, you need to make sure it has been drawn at least once prior to getting its extent.
To draw the figure,
plt.gcf().canvas.draw()
Complete code:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
base_ax = plt.subplot(111)
divider = make_axes_locatable(base_ax)
ax_right = divider.append_axes("right", size="20%", pad="1%")
ax_bottom = divider.append_axes("bottom", size="20%", pad="1%")
loc="upper left"
size = 20
plt.gcf().canvas.draw()
bbox = ax_right.get_window_extent()
ratio = bbox.width / bbox.height
inset_right_upper = inset_axes(
ax_right, width=str(size / ratio) + '%', height=str(size) + '%', loc=loc)
bbox = ax_bottom.get_window_extent()
ratio = bbox.width / bbox.height
inset_bottom_upper = inset_axes(
ax_bottom, width=str(size / ratio) + '%', height=str(size) + '%', loc=loc)
plt.show()
producing
Related Topics
Beautiful Soup 4 Find_All Don't Find Links That Beautiful Soup 3 Finds
Prepend a Level to a Pandas Multiindex
JSON.Loads Allows Duplicate Keys in a Dictionary, Overwriting the First Value
Efficiently Updating Database Using SQLalchemy Orm
Inserting the Same Value Multiple Times When Formatting a String
Pygame: Problems with Shooting in Space Invaders
How to Convert an H:Mm:Ss Time String to Seconds in Python
String Similarity Metrics in Python
How to Find Which Columns Contain Any Nan Value in Pandas Dataframe
How to Improve My Paw Detection
Python: How to Ignore an Exception and Proceed
How to Add Default Parameters to Functions When Using Type Hinting
How to Create a Decorator That Can Be Used Either with or Without Parameters
How to Interact with the Recaptcha Audio Element Using Selenium and Python