了解 maplotlib 以及如何使用单个数字格式化 matplotlib 轴?

Understanding maplotlib and how to format matplotlib axis with a single digit?

我很难让 seaborn 热图的标签只显示单个整数(即没有浮点数)。我有两个列表,它们构成了我使用 seaborn 绘制的数据框的轴。

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr

x = np.linspace(0, 15, 151)
y = np.linspace(0, 15, 151)
#substitute random data for my_data
df_map = pd.DataFrame(my_data, index = y, columns = x) 
plt.figure()
ax = sns.heatmap(df_map, square = True, xticklabels  = 20, yticklabels = 20)
ax.invert_yaxis()

我查看了许多答案和文档。我最大的问题是我没有什么经验,对 matplotlib 的理解也很差,而且文档感觉像是一种单独的语言……这是我尝试过的东西。

尝试 1::

解决方案的略微修改版本
fmtr = tkr.StrMethodFormatter('{x:.0f}')

plt.gca().xaxis.set_major_formatter(fmtr)

我很确定 tkr.StrMethodFormatter() 显示它在我的轴字符串中遇到的值的每 20 个索引,这可能是由于我在 sns.heatmap() 中的设置。我尝试将不同的字符串输入 tkr.StrMethodFormatter() 但没有成功。我查看了另外两个问题并尝试了 tkr 类 的不同组合,这些组合用于 and .

的答案

尝试 2:

fmtr = tkr.StrMethodFormatter("{x:.0f}")
locator = tkr.MultipleLocator(50)
fstrform = tkr.FormatStrFormatter('%.0f')

plt.gca().xaxis.set_major_formatter(fmtr)
plt.gca().xaxis.set_major_locator(locator)
#plt.gca().xaxis.set_major_formatter(fstrform)

现在我完全不知所措了。我发现 locator 更改了要绘制的第 n 个索引,并且 fmtrfstrform 都更改了显示的小数位数,但我这辈子都无法获得坐标轴显示轴列表中存在的整数值!

请帮忙!我已经挣扎了几个小时。这可能很简单,谢谢!

顺便说一句:

有人可以详细说明 问题中的文档摘录,特别是:

...and the field used for the position must be labeled pos.

此外,有人可以解释一下 tkr.StrMethodFormatter("{x:.0f}")tkr.FormatStrFormatter('%.0f') 之间的区别吗?我发现有两种方法产生相同的结果很烦人,每种方法都有自己的语法。

更新:

我花了一段时间才开始实施@ImportanceOfBeingErnest 提供的解决方案。我采取了额外的预防措施并将 x,y 数组中的数字四舍五入。我不确定这是否有必要,但我已经产生了我想要的结果:

x = np.linspace(0, 15, 151)
y = np.linspace(0, 15, 151)
# round float numbers in axes arrays
x_rounded = [round(i,3) for i in x]
y_rounded = [round(i,3) for i in y]
#substitute random data for my_data
df_map = pd.DataFrame(my_data, index = y_rounded , columns = x_rounded) 
plt.figure()
ax0 = sns.heatmap(df_map, square = True, xticklabels  = 20)
ax0.invert_yaxis()

labels = [label.get_text() for label in ax0.get_xticklabels()]
ax0.set_xticklabels(map(lambda x: "{:g}".format(float(x)), labels))

虽然我仍然不完全确定为什么会这样;检查我和他们之间的评论以进行澄清。

可悲的是,你没有做错任何事。问题在于 seaborn 有一种非常独特的方式来设置它的热图。
热图上的刻度线位于固定位置,并且具有固定标签。因此,要更改它们,需要更改那些固定标签。这样做的一种选择是收集标签,将它们转换回数字,然后再将它们设置回去。

labels = [label.get_text() for label in ax.get_xticklabels()]
ax.set_xticklabels(map(lambda x: "{:g}".format(float(x)), labels))

labels = [label.get_text() for label in ax.get_yticklabels()]
ax.set_yticklabels(map(lambda x: "{:g}".format(float(x)), labels))

提醒一句:原则上不要在没有设置位置的情况下设置刻度标签,但这里 seaborn 负责设置位置。我们只是相信它这样做是正确的。


如果你想要带有数字标签的数字轴可以按照问题中的尝试进行格式化,可以直接使用 matplotlib 图。

import numpy as np
import seaborn as sns # seaborn only imported to get its rocket cmap
import matplotlib.pyplot as plt

my_data = np.random.rand(150,150)
x = (np.linspace(0, my_data.shape[0], my_data.shape[0]+1)-0.5)/10
y = (np.linspace(0, my_data.shape[1], my_data.shape[1]+1)-0.5)/10


fig, ax = plt.subplots()
pc = ax.pcolormesh(x, y, my_data, cmap="rocket")
fig.colorbar(pc)
ax.set_aspect("equal")
plt.show()

虽然这已经开箱即用,但您仍可以按照问题中的尝试使用定位器和格式化程序。