我是 matplotlib 的新手,并尝试通过循环从 pandas 数据帧创建和保存绘图。每个图应具有相同的 x 轴,但 y 轴长度和标签不同。我可以毫无问题地创建和保存具有不同 y 轴长度和标签的图,但是当我创建图时,matplotlib 会根据左侧 y 轴标签需要多少空间来重新缩放 x 轴。图。
这些数字用于技术报告。我计划在报告的每一页上放置一个,并且希望所有 x 轴在页面上占据相同的空间量。
希望这些代码足以提供帮助。我确信其中有很多非最佳部分。
import pandas as pd
import matplotlib.pyplot as plt
import pylab as pl
from matplotlib import collections as mc
from matplotlib.lines import Line2D
import seaborn as sns
# elements for x-axis
start = -1600
end = 2001
interval = 200 # x-axis tick interval
xticks = [x for x in range(start, end, interval)] # create x ticks
# items needed for legend construction
lw_bins = [0,10,25,50,75,90,100] # bins for line width
lw_labels = [3,6,9,12,15,18] # line widths
def make_proxy(zvalue, scalar_mappable, **kwargs):
color = 'black'
return Line2D([0, 1], [0, 1], color=color, solid_capstyle='butt', **kwargs)
# generic image ID
img_path = r'C:\\Users\\user\\chart'
img_ID = 0
for line_subset in data:
# create line collection for this run through loop
lc = mc.LineCollection(line_subset)
# create plot and set properties
sns.set(style="ticks")
sns.set_context("notebook")
fig, ax = pl.subplots(figsize=(16, len(line_subset)*0.5)) # I want the height of the figure to change based on number of labels on y-axis
# Figure width should stay the same
ax.add_collection(lc)
ax.set_xlim(left=start, right=end)
ax.set_xticks(xticks)
ax.set_ylim(0, len(line_subset)+1)
ax.margins(0.05)
sns.despine(left=True)
ax.xaxis.set_ticks_position('bottom')
ax.set_yticks(line_subset['order'])
ax.set_yticklabels(line_subset['ylabel'])
ax.tick_params(axis='y', length=0)
# legend
proxies = [make_proxy(item, lc, linewidth=item) for item in lw_labels]
ax.legend(proxies, ['0-10%', '10-25%', '25-50%', '50-75%', '75-90%', '90-100%'], bbox_to_anchor=(1.05, 1.0),
loc=2, ncol=2, labelspacing=1.25, handlelength=4.0, handletextpad=0.5, markerfirst=False,
columnspacing=1.0)
# title
ax.text(0, len(line_subset)+2, s=str(img_ID), fontsize=20)
# save as .png images
plt.savefig(r'C:\\Users\\user\\Desktop\\chart' + str(img_ID) + '.png', dpi=300, bbox_inches='tight')
最佳答案
除非您使用专门定义纵横比的轴(例如在 imshow 图中或通过调用 .set_aspect("equal")
),否则轴占用的空间应仅取决于图形沿该方向的尺寸和设置为图形的间距。
因此,您几乎要求默认行为,唯一阻止您获得默认行为的是您在 savefig
命令中使用 bbox_inches='tight'
.
bbox_inches='tight'
将改变图形尺寸!所以不要使用它,轴的大小将保持不变。 `
你的图形大小,定义为figsize=(16, len(line_subset)*0.5)
根据我从问题中的理解似乎是有意义的。所以剩下的就是确保图形内的轴是您想要的尺寸。您可以通过使用 fig.add_axes
手动放置它来做到这一点
fig.add_axes([left, bottom, width, height])
其中 left、bottom、width、height
的图形坐标范围为 0 到 1。或者,您可以使用 subplots_adjust
调整子图外部的间距。
plt.subplots_adjust(left, bottom, right, top)
关于python - 使页面上所有子图的 x 轴长度相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43507107/