matplotlib 子图的常用 xlabel/ylabel

2025-03-04 08:23:00
admin
原创
87
摘要:问题描述:我有以下情节:fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size) 现在我想给这个图添加通用的 x 轴标签和 y 轴标签。“通用”的意思是整个子图网格下方应该有一个大的 x 轴标签,右侧应该有一个大的 y 轴标签。我在...

问题描述:

我有以下情节:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

现在我想给这个图添加通用的 x 轴标签和 y 轴标签。“通用”的意思是整个子图网格下方应该有一个大的 x 轴标签,右侧应该有一个大的 y 轴标签。我在 的文档中找不到有关此内容的任何信息plt.subplots,而且我的谷歌搜索建议我需要plt.subplot(111)先创建一个大的 - 但是我如何使用 将我的 5*2 子图放入其中plt.subplots


解决方案 1:

这看起来就是你真正想要的。它将这个答案的相同方法应用于您的具体情况:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True, figsize=(6, 6))

fig.text(0.5, 0.04, 'common X', ha='center')
fig.text(0.04, 0.5, 'common Y', va='center', rotation='vertical')

具有共同轴标签的多个图

解决方案 2:

Matplotlib v3.4 中的新功能pip install matplotlib --upgrade

supxlabelsupylabel

    fig.supxlabel('common_x')
    fig.supylabel('common_y')

参见示例:

import matplotlib.pyplot as plt

for tl, cl in zip([True, False, False], [False, False, True]):
    fig = plt.figure(constrained_layout=cl, tight_layout=tl)

    gs = fig.add_gridspec(2, 3)

    ax = dict()

    ax['A'] = fig.add_subplot(gs[0, 0:2])
    ax['B'] = fig.add_subplot(gs[1, 0:2])
    ax['C'] = fig.add_subplot(gs[:, 2])

    ax['C'].set_xlabel('Booger')
    ax['B'].set_xlabel('Booger')
    ax['A'].set_ylabel('Booger Y')
    fig.suptitle(f'TEST: tight_layout={tl} constrained_layout={cl}')
    fig.supxlabel('XLAgg')
    fig.supylabel('YLAgg')
    
    plt.show()

在此处输入图片描述
在此处输入图片描述
在此处输入图片描述

查看更多

解决方案 3:

由于我认为它足够相关且优雅(无需指定放置文本的坐标),因此我复制(略作修改)了另一个相关问题的答案。

import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, sharex=True, sharey=True, figsize=(6,15))
# add a big axis, hide frame
fig.add_subplot(111, frameon=False)
# hide tick and tick label of the big axis
plt.tick_params(labelcolor='none', which='both', top=False, bottom=False, left=False, right=False)
plt.xlabel("common X")
plt.ylabel("common Y")

结果如下(使用 matplotlib 版本 2.2.0):

具有公共 x 轴和 y 轴标签的 5 行 2 列子图

解决方案 4:

如果没有sharex=True, sharey=True你得到:

在此处输入图片描述

有了它你应该会变得更好:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))

plt.tight_layout()

在此处输入图片描述

但是如果您想添加额外的标签,您应该只将它们添加到边缘图:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))
        if i == len(axes2d) - 1:
            cell.set_xlabel("noise column: {0:d}".format(j + 1))
        if j == 0:
            cell.set_ylabel("noise row: {0:d}".format(i + 1))

plt.tight_layout()

在此处输入图片描述

为每个图添加标签会破坏它(也许有一种方法可以自动检测重复的标签,但我不知道)。

解决方案 5:

由于命令:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

您用来返回由图形和轴实例列表组成的元组,执行类似操作已经足够了(请注意我已更改fig,axfig,axes):

fig,axes = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

for ax in axes:
    ax.set_xlabel('Common x-label')
    ax.set_ylabel('Common y-label')

如果您碰巧想要更改特定子图上的某些细节,您可以通过在子图上迭代来访问axes[i]i

包含以下内容可能也会非常有帮助

fig.tight_layout()

在文件末尾,之前plt.show(),以避免标签重叠。

解决方案 6:

如果您通过在左下角为子图设置不可见标签来为常用标签预留空间,效果会更好。从 rcParams 传入字体大小也是不错的选择。这样,常用标签的大小将随您的 rc 设置而改变,轴也会调整以留出空间放置常用标签。

fig_size = [8, 6]
fig, ax = plt.subplots(5, 2, sharex=True, sharey=True, figsize=fig_size)
# Reserve space for axis labels
ax[-1, 0].set_xlabel('.', color=(0, 0, 0, 0))
ax[-1, 0].set_ylabel('.', color=(0, 0, 0, 0))
# Make common axis labels
fig.text(0.5, 0.04, 'common X', va='center', ha='center', fontsize=rcParams['axes.labelsize'])
fig.text(0.04, 0.5, 'common Y', va='center', ha='center', rotation='vertical', fontsize=rcParams['axes.labelsize'])

在此处输入图片描述
在此处输入图片描述

解决方案 7:

更新:

此功能现在是我最近在 pypi 上发布的proplot matplotlib 包的一部分。默认情况下,当您制作图形时,标签在子图之间“共享”。


原始答案:

我发现了一个更加强大的方法:

如果您知道初始化中的bottom和kwargs ,或者您知道轴在坐标中的边缘位置,那么您还可以使用一些奇特的“变换”魔法在坐标中指定 ylabel 位置。top`GridSpecFigureFigure`

例如:

import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
bottom, top = 0.1, 0.9
fig, axs = plt.subplots(nrows=2, ncols=1, bottom=bottom, top=top)
avepos = 0.5 * (bottom + top)
transform = mtransforms.blended_transform_factory(mtransforms.IdentityTransform(), fig.transFigure)  # specify x, y transform
axs[0].yaxis.label.set_transform(transform)  # changed from default blend (IdentityTransform(), axs[0].transAxes)
axs[0].yaxis.label.set_position((0, avepos))
axs[0].set_ylabel('Hello, world!')

...您应该看到标签仍然会适当调整左右以避免与标签重叠,就像平常一样,但也会将自己准确地定位在所需的子图之间。

值得注意的是,如果省略调用set_position,ylabel 将恰好显示在图形的中间位置。我猜这是因为当最终绘制标签时,matplotlib使用 0.5 作为y-coordinate,而没有检查底层坐标变换是否已更改。

解决方案 8:

我在绘制图表网格时遇到了类似的问题。图表由两部分组成(顶部和底部)。y 标签应该位于两个部分的中心。

我不想使用依赖于了解外部图形中的位置的解决方案(例如 fig.text()),因此我操纵了 set_ylabel() 函数的 y 位置。它通常是 0.5,即它添加到图的中间。由于我的代码中各部分之间的填充(hspace)为零,因此我可以计算出两个部分相对于上部的中间位置。

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

# Create outer and inner grid
outerGrid = gridspec.GridSpec(2, 3, width_ratios=[1,1,1], height_ratios=[1,1])
somePlot = gridspec.GridSpecFromSubplotSpec(2, 1,
               subplot_spec=outerGrid[3], height_ratios=[1,3], hspace = 0)

# Add two partial plots
partA = plt.subplot(somePlot[0])
partB = plt.subplot(somePlot[1])

# No x-ticks for the upper plot
plt.setp(partA.get_xticklabels(), visible=False)

# The center is (height(top)-height(bottom))/(2*height(top))
# Simplified to 0.5 - height(bottom)/(2*height(top))
mid = 0.5-somePlot.get_height_ratios()[1]/(2.*somePlot.get_height_ratios()[0])
# Place the y-label
partA.set_ylabel('shared label', y = mid)

plt.show()

图片

缺点:

  • 到图表的水平距离基于顶部,底部刻度可能会延伸到标签中。

  • 该公式没有考虑各部分之间的空间。

  • 当顶部高度为0时抛出异常。

可能存在一个将图形之间的填充考虑在内的通用解决方案。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3878  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2714  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   49  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   49  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   49  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用