【问题标题】:Format y axis as percent将 y 轴格式化为百分比
【发布时间】:2015-09-30 04:43:44
【问题描述】:

我有一个用熊猫创建的现有情节,如下所示:

df['myvar'].plot(kind='bar')

y 轴的格式为浮点数,我想将 y 轴更改为百分比。我发现的所有解决方案都使用 ax.xyz 语法,并且我只能将代码放在上面创建绘图的行下方(我不能将 ax=ax 添加到上面的行中。)

如何在不改变上述行的情况下将 y 轴格式化为百分比?

这是我找到的解决方案但需要我重新定义情节

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mtick

data = [8,12,15,17,18,18.5]
perc = np.linspace(0,100,len(data))

fig = plt.figure(1, (7,4))
ax = fig.add_subplot(1,1,1)

ax.plot(perc, data)

fmt = '%.0f%%' # Format you want the ticks, e.g. '40%'
xticks = mtick.FormatStrFormatter(fmt)
ax.xaxis.set_major_formatter(xticks)

plt.show()

上述解决方案的链接:Pyplot: using percentage on x axis

【问题讨论】:

标签: python pandas matplotlib plot


【解决方案1】:

如果 yticks 介于 0 和 1 之间,则另一种单行解决方案:

plt.yticks(plt.yticks()[0], ['{:,.0%}'.format(x) for x in plt.yticks()[0]])

【讨论】:

    【解决方案2】:

    您可以在一行中执行此操作而无需导入任何内容: plt.gca().yaxis.set_major_formatter(plt.FuncFormatter('{}%'.format))

    如果你想要整数百分比,你可以这样做: plt.gca().yaxis.set_major_formatter(plt.FuncFormatter('{:.0f}%'.format))

    您可以使用ax.yaxisplt.gca().yaxisFuncFormatter 仍然是 matplotlib.ticker 的一部分,但您也可以使用 plt.FuncFormatter 作为快捷方式。

    【讨论】:

      【解决方案3】:

      根据@erwanp的回答,可以使用Python 3的formatted string literals

      x = '2'
      percentage = f'{x}%' # 2%
      

      FuncFormatter() 内并与lambda 表达式结合。

      全部包装:

      ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: f'{y}%'))
      

      【讨论】:

        【解决方案4】:

        我迟到了,但我意识到这一点:ax 可以替换为plt.gca() 对于那些不使用轴而只使用子图的人。

        呼应@Mad Physicist 的答案,使用包PercentFormatter 会是:

        import matplotlib.ticker as mtick
        
        plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(1))
        #if you already have ticks in the 0 to 1 range. Otherwise see their answer
        

        【讨论】:

          【解决方案5】:

          这晚了几个月,但我用 matplotlib 创建了PR#6251 以添加一个新的PercentFormatter 类。使用这个类,您只需要一行来重新格式化您的轴(如果您计算 matplotlib.ticker 的导入,则需要两条):

          import ...
          import matplotlib.ticker as mtick
          
          ax = df['myvar'].plot(kind='bar')
          ax.yaxis.set_major_formatter(mtick.PercentFormatter())
          

          PercentFormatter() 接受三个参数,xmaxdecimalssymbolxmax 允许您设置对应于轴上 100% 的值。如果您有从 0.0 到 1.0 的数据并且您希望将其从 0% 显示到 100%,这很好。只需PercentFormatter(1.0)

          另外两个参数可以设置小数点后的位数和符号。它们分别默认为None'%'decimals=None 将根据您显示的轴数自动设置小数位数。

          更新

          PercentFormatter 在 2.1.0 版中被引入到 Matplotlib 中。

          【讨论】:

          • 这非常有效。但是 PercentFormatter(1.0) 似乎格式化为 10.0% 20.0% 而不是 10% 20% (也许你的答案有错字?)
          • @DrXorile。最有可能更新 matplotlib。官方文档取代了这里的任何内容。有机会我可以比较
          • 哦,我想是因为默认是decimal=None,它会根据范围自动生成小数位数。因此,如果范围小于 50%,则为 10.0%。超过 50% 是 10%。所以很抱歉 - 你的答案是正确的,取决于其他参数。
          • 你将如何应用到次 y 轴?
          • @JeJe。您可以在您想要的任何轴上设置格式化程序
          【解决方案6】:

          我建议使用seaborn 的替代方法

          工作代码:

          import pandas as pd
          import seaborn as sns
          data=np.random.rand(10,2)*100
          df = pd.DataFrame(data, columns=['A', 'B'])
          ax= sns.lineplot(data=df, markers= True)
          ax.set(xlabel='xlabel', ylabel='ylabel', title='title')
          #changing ylables ticks
          y_value=['{:,.2f}'.format(x) + '%' for x in ax.get_yticks()]
          ax.set_yticklabels(y_value)
          

          【讨论】:

            【解决方案7】:

            pandas 数据框图将为您返回 ax,然后您就可以开始任意操作坐标轴了。

            import pandas as pd
            import numpy as np
            
            df = pd.DataFrame(np.random.randn(100,5))
            
            # you get ax from here
            ax = df.plot()
            type(ax)  # matplotlib.axes._subplots.AxesSubplot
            
            # manipulate
            vals = ax.get_yticks()
            ax.set_yticklabels(['{:,.2%}'.format(x) for x in vals])
            

            【讨论】:

            • 这将在您以交互方式平移/缩放图形时产生不良影响
            • 比尝试使用matplotlib.ticker 函数格式化程序容易上百万倍!
            • 你如何将 y 轴限制为 (0,100%)?我试过 ax.set_ylim(0,100) 但这似乎不起作用!!
            • @mpour 仅更改了 yticks 的标签,因此限制仍为自然单位。设置 ax.set_ylim(0, 1) 就可以了。
            • 不知道为什么,但是这个答案错误地标记了刻度,而 erwanp 正确标记了整个轴。
            【解决方案8】:

            对于那些正在寻找快速单线的人:

            plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) for x in plt.gca().get_yticks()]) 
            

            或者如果您使用 Latex 作为轴文本格式化程序,则必须添加一个反斜杠 '\'

            plt.gca().set_yticklabels(['{:.0f}\%'.format(x*100) for x in plt.gca().get_yticks()]) 
            

            【讨论】:

            • 对我来说,Daniel Himmelstein 的回答有效,而这个回答改变了规模
            【解决方案9】:

            Jianxun 的解决方案为我完成了这项工作,但破坏了窗口左下角的 y 值指示器。

            我最终改用了FuncFormatter(并且还按照here的建议去除了不必要的尾随零):

            import pandas as pd
            import numpy as np
            from matplotlib.ticker import FuncFormatter
            
            df = pd.DataFrame(np.random.randn(100,5))
            
            ax = df.plot()
            ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y))) 
            

            一般来说,我建议使用FuncFormatter 进行标签格式化:它可靠且用途广泛。

            【讨论】:

            • 您可以进一步简化代码:ax.yaxis.set_major_formatter(FuncFormatter('{0:.0%}'.format))。 AKA 不需要 lambda,让格式完成工作。
            • @DanielHimmelstein 你能解释一下吗?特别是在 { } 内。不确定我的 0.06 是如何使用 python 格式变成 6% 的。也是很好的解决方案。似乎比使用 .set_ticklabels 更可靠
            • @DChaps '{0:.0%}'.format 创建一个formatting function。冒号前的0 告诉格式化程序用传递给函数的第一个参数替换花括号及其内容。冒号后面的部分,.0%,告诉格式化程序如何呈现值。 .0 指定 0 位小数,% 指定渲染为百分比。
            猜你喜欢
            • 2017-06-21
            • 2020-03-18
            • 1970-01-01
            • 1970-01-01
            • 2021-05-10
            • 2020-06-01
            相关资源
            最近更新 更多