Issue
I want to draw a set of polygons on an axis of equal aspect and apply tight layout on the figure.
However, it seems like the figure size doesn't get correctly adjusted when equal aspect and tight layout are used together.
Attempt 1
Equal aspect and tight layout
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
fig, ax = plt.subplots(1,1)
l = 5
h = 1
poly = Polygon(
np.array([
[0,0],
[l,0],
[l,h],
[0,h]
]),
edgecolor="black",
facecolor="gray",
)
ax.add_patch(poly)
ax.set_aspect("equal")
ax.set_xlim(0,l)
ax.set_ylim(0,h)
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$", rotation=0, labelpad=5)
fig.tight_layout(pad=0.25)
plt.show()
Output: notice the extra space on top and bottom. Also notice that the y axis label is out of bounds.
Attempt 2
Tight layout without equal aspect
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
fig, ax = plt.subplots(1,1)
l = 5
h = 1
poly = Polygon(
np.array([
[0,0],
[l,0],
[l,h],
[0,h]
]),
edgecolor="black",
facecolor="gray",
)
ax.add_patch(poly)
# ax.set_aspect("equal")
ax.set_xlim(0,l)
ax.set_ylim(0,h)
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$", rotation=0, labelpad=5)
fig.tight_layout(pad=0.25)
plt.show()
Output: works well, except that the aspect ratio is unequal
How to achieve tight layout and equal aspect ratio?
Solution
Additional margins appear if the aspect ratio of the Figure (default size from rcParams["figure.figsize"]
defaults to [6.4, 4.8]
, i.e. an aspect ratio of 1.33) differs from the aspect ratio of the Axes. To avoid this, you need to adjust the aspect ratio of the Figure to match the aspect ratio of the Axes including ticks and labels. You can get it using get_tightbbox
after you have drawn the Figure (for instance using draw_without_rendering
).
For better visual result I recommend using constrained
rather than tight
layout.
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
fig, ax = plt.subplots(1,1, layout='constrained')
l = 5
h = 1
fig.set_size_inches(10,2)
poly = Polygon(
np.array([
[0,0],
[l,0],
[l,h],
[0,h]
]),
edgecolor="black",
facecolor="gray",
)
ax.add_patch(poly)
ax.set_aspect("equal")
ax.set_xlim(0,l)
ax.set_ylim(0,h)
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$", rotation=0, labelpad=5)
# adjust Figure aspect ratio to match Axes
fig.draw_without_rendering()
tb = fig.get_tightbbox(fig.canvas.get_renderer())
fig.set_size_inches(tb.width, tb.height)
plt.show()
Answered By - Stef
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.