失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > python plot label_python - matplotlib子图的通用xlabel / ylabel

python plot label_python - matplotlib子图的通用xlabel / ylabel

时间:2020-03-06 21:53:35

相关推荐

python plot label_python  -  matplotlib子图的通用xlabel / ylabel

python - matplotlib子图的通用xlabel / ylabel

我有以下情节:

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

现在我想给这个图绘制常见的x轴标签和y轴标签。 使用" common",我的意思是在整个子图网格下面应该有一个大的x轴标签,在右边有一个大的y轴标签。 我在plt.subplots的文档中找不到任何相关内容,我的谷歌搜索建议我需要制作一个大的plt.subplot(111) - 但是如何使用plt.subplots将我的5 * 2子图表放入其中?

jolindbe asked -08-08T13:12:21Z

7个解决方案

152 votes

这看起来像你真正想要的。 它对您的具体案例采用与此答案相同的方法:

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')

divenex answered -08-08T13:12:37Z

31 votes

如果没有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()

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

Piotr Migdal answered -08-08T13:13:24Z

14 votes

由于命令:

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

你使用过返回一个由图形和轴实例列表组成的元组,它已经足够做(比如我已经改变了plt.show()到i):

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')

如果您碰巧想要更改特定子图上的某些细节,可以通过plt.show()访问它,其中i遍历您的子图。

包含一个可能也非常有帮助

fig.tight_layout()

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

Marius answered -08-08T13:14:20Z

13 votes

由于我认为它相关且足够优雅(不需要指定坐标来放置文本),我复制(略微改编)对另一个相关问题的答案。

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', top=False, bottom=False, left=False, right=False)

plt.xlabel("common X")

plt.ylabel("common Y")

这导致以下结果(使用matplotlib 2.2.0版):

bli answered -08-08T13:14:56Z

2 votes

我在绘制图形网格时遇到了类似的问题。 图表由两部分组成(顶部和底部)。 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时引发异常。

可能存在一种通用解决方案,其将数字之间的填充考虑在内。

CPe answered -08-08T13:16:11Z

2 votes

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

如果您知道进入y初始化的set_position和matplotlib kwargs,或者您知道轴的边缘位置在set_position坐标中,您还可以在Figure坐标中指定ylabel位置,并使用某些奇特的变换" 魔法。 例如:

import matplotlib.transforms as mtransforms

bottom, top = .1, .9

f, a = plt.subplots(nrows=2, ncols=1, bottom=bottom, top=top)

avepos = (bottom+top)/2

a[0].yaxis.label.set_transform(mtransforms.blended_transform_factory(

mtransforms.IdentityTransform(), f.transFigure # specify x, y transform

)) # changed from default blend (IdentityTransform(), a[0].transAxes)

a[0].yaxis.label.set_position((0, avepos))

a[0].set_ylabel('Hello, world!')

......你应该看到标签仍然适当地左右调整以防止与标签重叠,就像正常一样 - 但现在它将调整为始终正好在所需的子图之间。

此外,如果你甚至不使用set_position,那么默认情况下ylabel将显示在该数字的一半。 我猜测这是因为当最终绘制标签时,matplotlib使用0.5作为y坐标,而不检查基础坐标变换是否已更改。

Luke Davis answered -08-08T13:17:01Z

1 votes

如果通过为左下角的子图制作隐形标签为常用标签保留空间,效果会更好。 从rcParams传入fontsize也很好。 这样,常用标签将根据您的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'])

EL_DON answered -08-08T13:17:29Z

如果觉得《python plot label_python - matplotlib子图的通用xlabel / ylabel》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。