python - 使页面上所有子图的 x 轴长度相同

标签 python python-2.7 matplotlib seaborn subplot

我是 matplotlib 的新手,并尝试通过循环从 pandas 数据帧创建和保存绘图。每个图应具有相同的 x 轴,但 y 轴长度和标签不同。我可以毫无问题地创建和保存具有不同 y 轴长度和标签的图,但是当我创建图时,matplotlib 会根据左侧 y 轴标签需要多少空间来重新缩放 x 轴。图。

这些数字用于技术报告。我计划在报告的每一页上放置一个,并且希望所有 x 轴在页面上占据相同的空间量。

这是我得到的和我想要得到的 MSPaint 版本。 MSPaint-drawn plot examples of the problem and desired solution

希望这些代码足以提供帮助。我确信其中有很多非最佳部分。

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/

相关文章:

python - 输入提示不会结束

python - 如何在 x 轴上绘制带有日期时间的线性回归

python - 制作图后 Matplotlib 图更改以供发布

python - 如何在 TPU 的其他模型中使用 keras 模型

python - google-app-engine firebase-admin python

python - 将 Matplotlib 和 Sympy 的图放在一起

python - 使用 groupby 的结果过滤 pandas 数据框

python - 正则表达式 (vim) 用于 print ... to print(...) 用于 python2 到 python3

python - 将 pandas dataframe 转换为 PySpark RDD 时遇到问题?

python - matplotlib 中的金字塔 3D 直方图(如 1976 年有关 SVD 的历史电影)