plt.tight_layout()
通过更改轴大小来工作,因此图中的所有元素都适合该图框。
请参阅:
y=np.random.normal(size=100)
fig, ax = plt.subplots(); plt.plot(y)
plt.xlabel('time / s.', fontsize=40)
fig.set_size_inches([5, 2])
plt.tight_layout()
调整轴的大小,使所有元素都适合图形。我希望我的轴尺寸保持不变。是否有替代方案可以在保持轴不变的情况下调整图形的大小?
答案 0 :(得分:1)
轴的尺寸以图形坐标表示。即默认情况下,单个子图是图宽宽的77.5%,图高的77%是高。因此,在更改图形尺寸时,不能保持轴不受影响,因为一个轴取决于另一个。
现在它取决于调用tight_layout
的目标和所需的输出。
运行问题中的代码会产生下图,
可以看出,超大的x标签被切断了。
例如,如果你有兴趣保存你的数字,你可以不调用tight_layout()
而是在savefig调用中指定bbox_inches="tight"
。
plt.savefig("some.png", bbox_inches="tight")
这将生成一个比原始图形大的图形,而不会改变内部对象的任何位置。因此它与tight_layout
不同,因为它根本不会改变布局和间距。这里的缺点是它只会影响保存的图形,而不会影响屏幕上显示的图形。
现在你原则上可以对你屏幕上的数字做同样的事情。这非常hacky,会对轴的存储方式产生影响。以下是一个函数tight_figure
,它将图像视为已保存,但让它保留在屏幕上的原始画布中。
import numpy as np
import matplotlib.pyplot as plt
import io
from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
from matplotlib import tight_bbox
def tight_figure(fig,**kwargs):
canvas = fig.canvas._get_output_canvas("png")
print_method = getattr(canvas, 'print_png')
print_method(io.BytesIO(), dpi=fig.dpi,
facecolor=fig.get_facecolor(), dryrun=True)
renderer = fig._cachedRenderer
bbox_inches = fig.get_tightbbox(renderer)
bbox_artists = fig.get_default_bbox_extra_artists()
bbox_filtered = []
for a in bbox_artists:
bbox = a.get_window_extent(renderer)
if a.get_clip_on():
clip_box = a.get_clip_box()
if clip_box is not None:
bbox = Bbox.intersection(bbox, clip_box)
clip_path = a.get_clip_path()
if clip_path is not None and bbox is not None:
clip_path = \
clip_path.get_fully_transformed_path()
bbox = Bbox.intersection(
bbox, clip_path.get_extents())
if bbox is not None and (
bbox.width != 0 or bbox.height != 0):
bbox_filtered.append(bbox)
if bbox_filtered:
_bbox = Bbox.union(bbox_filtered)
trans = Affine2D().scale(1.0 / fig.dpi)
bbox_extra = TransformedBbox(_bbox, trans)
bbox_inches = Bbox.union([bbox_inches, bbox_extra])
pad = kwargs.pop("pad_inches", None)
if pad is None:
pad = plt.rcParams['savefig.pad_inches']
bbox_inches = bbox_inches.padded(pad)
tight_bbox.adjust_bbox(fig, bbox_inches, canvas.fixed_dpi)
w = bbox_inches.x1 - bbox_inches.x0
h = bbox_inches.y1 - bbox_inches.y0
fig.set_size_inches(w,h)
y=np.random.normal(size=100)
fig, ax = plt.subplots(); plt.plot(y)
plt.xlabel('time / s.', fontsize=40)
fig.set_size_inches([5, 2])
tight_figure(fig)
plt.show()