【问题标题】:How can I reduce the amount of decimals in contour plot legend?如何减少等高线图图例中的小数位数?
【发布时间】:2020-09-22 08:12:13
【问题描述】:

我试图为图例只保留一位小数。绘图所基于的数据 (w_field) 具有 8 位小数的值。

w_field = np.genfromtxt('w_field.dat') 
CV = plt.contour(w_field)
x,Vel = CV.legend_elements()
plt.legend(x,Vel, title= 'Vertical velocity (m/s)', fontsize= 10, bbox_to_anchor=(1.05, 1), loc='upper left') 
plt.xlabel('Nx')
plt.ylabel('Ny')

【问题讨论】:

标签: python matplotlib legend


【解决方案1】:

函数CV.legend_elements() 接受一个格式化参数,它应该是一个返回格式化字符串的函数。这是一个示例,显示了与默认格式的区别。

from matplotlib import pyplot as plt
import numpy as np

w_field = np.random.randn(60, 100).cumsum(axis=1).cumsum(axis=0) / 50
CV = plt.contour(w_field)
x, Vel = CV.legend_elements()
legend1 = plt.legend(x, Vel, title='Default formatting', fontsize=10, bbox_to_anchor=(1.02, 1.02), loc='upper left')
x, Vel = CV.legend_elements(str_format=lambda x: f'{x:.1f}')
plt.legend(x, Vel, title='With formatting function', fontsize=10, bbox_to_anchor=(1.02, 0), loc='lower left')
plt.gca().add_artist(legend1)  # matplotlib removes the legend when a second legend is created, here it is added again
plt.tight_layout()
plt.show()

PS:即使是official example from the documents 也会显示这种奇怪的格式。

【讨论】:

  • 很好的答案!如果您像这样格式化字符串,它看起来会更好:x, Vel = CV.legend_elements(str_format=lambda x: f'{x: .1f}')
  • @Scotty1- 一定有什么东西在逃避我。您只是在冒号后添加一个空格?这有什么不同吗?
  • @JohanC 是的,它为正数引入了一个空格,这样正数和负数就在第一位对齐。
  • @Scotty1- 好的,不知道那个。谢谢。不幸的是,它在这种情况下不起作用,因为plt.contourlegend_elements 强制进行TeX 渲染,总是在数字周围添加'$x = ...$'。此外,TeX 的减号比一个空格宽得多。
  • 哦,对了,不知怎么的,TeX 渲染有问题。现在重新启动会重现您描述的行为。在这种情况下,用显式加号替换空白将使格式更好:x, Vel = CV.legend_elements(str_format=lambda x: f'{x:+.1f}')。不幸的是,我不知道任何内置的 TeX 命令来制作正确大小的间距而不是加号。在 Latex 中,我会使用 SIunitx 或 align env。为此目的,但在 matplotlib 中实现它相当复杂......
【解决方案2】:

这应该可行。

fig, ax = plt.subplots()
w_field = np.genfromtxt('w_field.dat') 
CV = ax.contour(w_field)
x,Vel = CV.legend_elements()
plt.legend(x,Vel, title= 'Vertical velocity (m/s)', fontsize= 10, bbox_to_anchor=(1.05, 1), loc='upper left') 
plt.xlabel('Nx')
plt.ylabel('Ny')

leg = ax.get_legend()

for lbl in leg.get_texts():
    label_text = lbl.get_text()
    float_num = label_text.split()[2]
    new_text = f'X = {float(float_num):,.1f}'
    lbl.set_text(new_text)

【讨论】:

    猜你喜欢
    • 2021-01-04
    • 2016-09-03
    • 2014-09-09
    • 1970-01-01
    • 2012-04-28
    • 2018-04-29
    • 1970-01-01
    • 2018-07-26
    相关资源
    最近更新 更多