[英]Matplotlib - logarithmic chart - adding extra text to chart
我正在尝试基于 pandas dataframe 创建对数图表的可读布局。 我有以下代码:
fig, ax = plt.subplots(figsize=(15, 8))
ax.clear()
ax.barh(mydataframe['Labels'], mydataframe['Values']
plt.xscale('log')
for i, (label, value) in enumerate(zip(mydataframe['Labels'], mydataframe['Values'])):
ax.text(value + 1, i, f'{value:,.0f}', size=8, ha='left', va='center')
ax.text(value + 20, i, f'({int(round(extraValue1)):d} -- {extraValue2:,.2f}%)', size=8, ha='left', va='center')
如图所示,我的问题是图表上第二个 ax.text 打印的 alignment。 ax.text 的第一行完美地对齐每个条末尾的值。 但是第二个,随着我需要添加的附加信息,alignment 搞砸了并覆盖了以前的值,我们 go 越多到更大的条。 有谁知道我该如何解决这个问题? 我感觉这与使用对数刻度设置的图表有关。 extravalue1 和 2 也是 mydataframe 列的一部分,但为了代码的简单性,我在这里定义了仅主要列的枚举
为了使条形图和文本之间有一个很好的距离,最好使用文本x
的精确值,并以一两个空格开始文本。 因此,使用ax.text(value, i, " abc")
而不是ax.text(value+20, i, "abc")
。 要拥有两个文本,只需将它们连接起来并将它们放在一个 go 中。
如果您想要包含多个 colors 的文本,并将它们放置在一起,并有一个适合第一个文本长度的间隙,可以使用偏移框。
要为文本留出更多空间,您可以增加 x 边距,例如ax.margins(x=0.2)
。 同时,您可以减少 y 边距,这里的默认值有点太大。
import matplotlib.pyplot as plt
from matplotlib.colors import CSS4_COLORS
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker
import numpy as np
fig, ax = plt.subplots(figsize=(15, 8))
labels = ["".join(np.random.choice(list('abcdef'), 5)) for _ in range(20)]
values = np.sort(10 ** np.random.uniform(1, 5, 20))
ax.barh(labels, values, color=np.random.choice(list(CSS4_COLORS.keys()), 20))
ax.set_xscale('log')
for i, (label, value, extraValue1, extraValue2) in enumerate(
zip(labels, values, *np.random.randint(100, 1000, (2, 20)))):
xbox1 = TextArea(f'{value:,.0f}', textprops=dict(color="crimson", size=8, ha='left', va='baseline'))
xbox2 = TextArea(f'({int(round(extraValue1)):d} -- {extraValue2:,.2f}%)',
textprops=dict(color="navy", size=8, ha='left', va='baseline'))
xbox = HPacker(children=[xbox1, xbox2], align="baseline", pad=0, sep=5)
anchored_xbox = AnchoredOffsetbox(loc="center left", child=xbox, pad=0.5, frameon=False, bbox_to_anchor=(value, i),
borderpad=0, bbox_transform=ax.transData)
ax.add_artist(anchored_xbox)
ax.margins(x=0.2, y=0.01)
plt.show()
只需将您想要的文本添加到 plot 作为一个字符串不要:
for i, (label, value) in enumerate(zip(mydataframe['Labels'], mydataframe['Values'])):
text = f'{value:,.0f}\t({int(round(extraValue1)):d} -- {extraValue2:,.2f}%)'
ax.text(value + 1, i, text, size=8, ha='left', va='center')
或者我错过了什么你不想这样做的原因?
由于您的 x 轴是对数的,因此您希望对文本使用乘法偏移量,而不是加法偏移量。 也就是说,尝试value * 1.2
而不是value + 20
:
fig, ax = plt.subplots(figsize=(15, 8))
ax.clear()
ax.barh(mydataframe['Labels'], mydataframe['Values']
plt.xscale('log')
for i, (label, value) in enumerate(zip(mydataframe['Labels'], mydataframe['Values'])):
ax.text(value * 1.05, i, f'{value:,.0f}', size=8, ha='left', va='center')
ax.text(value * 1.2, i, f'({int(round(extraValue1)):d} -- {extraValue2:,.2f}%)', size=8, ha='left', va='center')
请调整1.05
和1.2
以满足您的需求。 如果您将两个文本合并为一个,格式可能会看起来更好,但这只是品味。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.