Home > other >  Set the size and location of a subplot within a window of specific size in matplotlib
Set the size and location of a subplot within a window of specific size in matplotlib

Time:07-25

I want to exactly define the location and size of a single subplot within an entire plot. I define the subplot like below:

plt.figure(figsize=(12, 12)) # ignored
fig, ax = plt.subplots(1, 1, figsize=get_figsize(min_bounds, max_bounds), dpi=150)

It seems to me that the code above does NOT affect the size of the subplot, but of the entire plot (I want to set the size of the entire plot independently). Ideally I would like to say: "I want to place my subplot of size (x, y) at the position (e.g. top-left coordinate of subplot) (u, v) within my window of bigger size". How could I achieve that?

CodePudding user response:

Sounds like you may want Figure.add_axes This method takes a list of 4 values as its argument to specify the coordinate of the lower left hand corner of the Axes as well as its width and height: [x, y, width, height]

The coordinate system on the Figure is fractional meaning its horizontal axis spans from 0 to 1, and its vertical axis also spans from 0 to 1.

import matplotlib.pyplot as plt
from numpy import linspace, sin
from numpy.random import default_rng

rng = default_rng(0)

xs = linspace(0, 5)
sin_ys = sin(xs)
linear_ys = xs   rng.normal(scale=4, size=xs.size)

fig = plt.figure()

# add axes whose lower left corner is at (.2, .7) with width of .4 and height of .2
ax0 = fig.add_axes([.2, .7, .4, .2])
ax0.plot(xs, sin_ys)

# add axes whose lower left corner is at (.7, .1) with width of .2 and height of .5
ax1 = fig.add_axes([.7, .1, .2, .5])
ax1.scatter(xs, linear_ys, s=8)

plt.show()

enter image description here


As a note- if you're working in a Jupyter Notebook, make sure you are either saving the plot manually and viewing it, or using a GUI backend (like %matplotlib nbagg) or else the default for Jupyter (%matplotlib inline) will tighten your layout for you by default, removing empty whitespace from your figure.


update with set_aspect('equal') Note that when using this method, your width or height will change in accordance with the plotted data. This is unavoidable.

import matplotlib.pyplot as plt
from numpy import linspace, sin
from numpy.random import default_rng

fig = plt.figure(figsize=(12, 6))
y = 0
w, h = .2, 1


ax0 = fig.add_axes([0, y, w, h])
ax0.set_title('original')

ax1 = fig.add_axes([.25, y, w, h])
# anchor='C' is the default
ax1.set_aspect('equal', anchor='C')
ax1.set_title('equal aspect\nCentered anchor')

ax2 = fig.add_axes([.5, y, w, h])

# Resize & move plot to the lower right (South East; SE)
#   corner of the original Axes area 
ax2.set_aspect('equal', anchor='SE')
ax2.set_title('equal aspect\nSE anchor')

ax3 = fig.add_axes([.75, y, w, h])

# Resize & move plot to the lower right (South East; SE)
#   corner of the original Axes area 
ax3.set_aspect('equal', anchor='NW')
ax3.set_title('equal aspect\nNW anchor')

for ax in fig.axes:
    ax.yaxis.set_visible(False)
    ax.xaxis.set_visible(False)
    
plt.show()

enter image description here

  • Related