如何在分组的柱形图上显示自定义数值?

huangapple go评论79阅读模式
英文:

How can I display custom values over grouped bars?

问题

这是你要翻译的内容:

I have a barplot with this values in a `dict` for the C/C):

{'Country Name': {0: 'United States',
  1: 'United States',
  2: 'United States',
  3: 'United States',
  4: 'Russian Federation',
  5: 'Russian Federation',
  6: 'Russian Federation',
  7: 'Russian Federation',
  8: 'Japan',
  9: 'Japan',
  10: 'Japan',
  11: 'Japan',
  12: 'Germany',
  13: 'Germany',
  14: 'Germany',
  15: 'Germany',
  16: 'France',
  17: 'France',
  18: 'France',
  19: 'France'},
 'Indicator Name': {0: 'Population, total',
  1: 'Population, ages 0-14, total',
  2: 'Population, ages 15-64, total',
  3: 'Population, ages 65+, total',
  4: 'Population, total',
  5: 'Population, ages 0-14, total',
  6: 'Population, ages 15-64, total',
  7: 'Population, ages 65+, total',
  8: 'Population, total',
  9: 'Population, ages 0-14, total',
  10: 'Population, ages 15-64, total',
  11: 'Population, ages 65+, total',
  12: 'Population, total',
  13: 'Population, ages 0-14, total',
  14: 'Population, ages 15-64, total',
  15: 'Population, ages 65+, total',
  16: 'Population, total',
  17: 'Population, ages 0-14, total',
  18: 'Population, ages 15-64, total',
  19: 'Population, ages 65+, total'},
 'Valeur': {0: 320896618.0,
  1: 61653419.0,
  2: 212262832.0,
  3: 46980367.0,
  4: 144096870.0,
  5: 24255306.0,
  6: 100404879.0,
  7: 19436685.0,
  8: 127141000.0,
  9: 16517168.0,
  10: 77547638.0,
  11: 33076194.0,
  12: 81686611.0,
  13: 10716271.0,
  14: 53720119.0,
  15: 17250221.0,
  16: 66624068.0,
  17: 12168975.0,
  18: 41837530.0,
  19: 12617563.0}}

Code for the barplot  (with the ax because I tried containers):

ax = plt.figure(figsize=(10,5))
ax = sns.barplot(data = Graph1values, x = 'Country Name', y = 'Valeur', hue = 'Indicator Name',palette="dark")
ax = plt.xlabel('')
ax = plt.ylabel('Nombre de personnes', size = 15)
ax = plt.title('Etude de la répartition de la population', size = 20)

ax = plt.show()

[![enter image description here][1]][1]

I want to add these values on top of the bars

x = ['100%', '19%', '66%', '15%', '100%', '17%', '70%', '13%', '100%', '13%', '61%', '26%', '100%',
 '13%', '66%', '21%', '100%', '18%', '63%', '19%']

I tried with containers, but it does not work.

只提供翻译,不包括问题的回答:

我有一个条形图其中包含一个`dict`中的这些值用于C/C):

{'Country Name': {0: '美国',
  1: '美国',
  2: '美国',
  3: '美国',
  4: '俄罗斯联邦',
  5: '俄罗斯联邦',
  6: '俄罗斯联邦',
  7: '俄罗斯联邦',
  8: '日本',
  9: '日本',
  10: '日本',
  11: '日本',
  12: '德国',
  13: '德国',
  14: '德国',
  15: '德国',
  16: '法国',
  

<details>
<summary>英文:</summary>

I have a barplot with this values in a `dict` for the C/C):

    {&#39;Country Name&#39;: {0: &#39;United States&#39;,
      1: &#39;United States&#39;,
      2: &#39;United States&#39;,
      3: &#39;United States&#39;,
      4: &#39;Russian Federation&#39;,
      5: &#39;Russian Federation&#39;,
      6: &#39;Russian Federation&#39;,
      7: &#39;Russian Federation&#39;,
      8: &#39;Japan&#39;,
      9: &#39;Japan&#39;,
      10: &#39;Japan&#39;,
      11: &#39;Japan&#39;,
      12: &#39;Germany&#39;,
      13: &#39;Germany&#39;,
      14: &#39;Germany&#39;,
      15: &#39;Germany&#39;,
      16: &#39;France&#39;,
      17: &#39;France&#39;,
      18: &#39;France&#39;,
      19: &#39;France&#39;},
     &#39;Indicator Name&#39;: {0: &#39;Population, total&#39;,
      1: &#39;Population, ages 0-14, total&#39;,
      2: &#39;Population, ages 15-64, total&#39;,
      3: &#39;Population, ages 65+, total&#39;,
      4: &#39;Population, total&#39;,
      5: &#39;Population, ages 0-14, total&#39;,
      6: &#39;Population, ages 15-64, total&#39;,
      7: &#39;Population, ages 65+, total&#39;,
      8: &#39;Population, total&#39;,
      9: &#39;Population, ages 0-14, total&#39;,
      10: &#39;Population, ages 15-64, total&#39;,
      11: &#39;Population, ages 65+, total&#39;,
      12: &#39;Population, total&#39;,
      13: &#39;Population, ages 0-14, total&#39;,
      14: &#39;Population, ages 15-64, total&#39;,
      15: &#39;Population, ages 65+, total&#39;,
      16: &#39;Population, total&#39;,
      17: &#39;Population, ages 0-14, total&#39;,
      18: &#39;Population, ages 15-64, total&#39;,
      19: &#39;Population, ages 65+, total&#39;},
     &#39;Valeur&#39;: {0: 320896618.0,
      1: 61653419.0,
      2: 212262832.0,
      3: 46980367.0,
      4: 144096870.0,
      5: 24255306.0,
      6: 100404879.0,
      7: 19436685.0,
      8: 127141000.0,
      9: 16517168.0,
      10: 77547638.0,
      11: 33076194.0,
      12: 81686611.0,
      13: 10716271.0,
      14: 53720119.0,
      15: 17250221.0,
      16: 66624068.0,
      17: 12168975.0,
      18: 41837530.0,
      19: 12617563.0}}

Code for the barplot  (with the ax because I tried containers):

    ax = plt.figure(figsize=(10,5))
    ax = sns.barplot(data = Graph1values, x = &#39;Country Name&#39;, y = &#39;Valeur&#39;, hue = &#39;Indicator Name&#39;,palette=&quot;dark&quot;)
    ax = plt.xlabel(&#39;&#39;)
    ax = plt.ylabel(&#39;Nombre de personnes&#39;, size = 15)
    ax = plt.title(&#39;Etude de la r&#233;partition de la population&#39;, size = 20)
        
    ax = plt.show()

[![enter image description here][1]][1]

**I want to add these values on top of the bars**

    x = [&#39;100%&#39;, &#39;19%&#39;, &#39;66%&#39;, &#39;15%&#39;, &#39;100%&#39;, &#39;17%&#39;, &#39;70%&#39;, &#39;13%&#39;, &#39;100%&#39;, &#39;13%&#39;, &#39;61%&#39;, &#39;26%&#39;, &#39;100%&#39;,
     &#39;13%&#39;, &#39;66%&#39;, &#39;21%&#39;, &#39;100%&#39;, &#39;18%&#39;, &#39;63%&#39;, &#39;19%&#39;]

I tried with containers, but it does not work.


  [1]: https://i.stack.imgur.com/mjYqF.png

</details>


# 答案1
**得分**: 1

以下是翻译的内容

- 似乎`dict`必须是DataFrame的输出但这不在问题中显示
- 使用[`.bar_label`][1]来在每个条形图的顶部添加自定义标签[如何在条形图上添加值标签][2]中有该方法的详细解释
  - 使用条形图的高度(`h`),`country`和容器`label`,以及DataFrame上的[布尔索引][3]以获取正确的`'percents'`来注释条形图
  - [此问题][4]的答案没有展示如何获取条形图的自定义值
- 不要将所有行分配给`ax`,因为它们不返回`matplotlib.axes`。这会覆盖`ax`,因此`ax.bar_label`不起作用
  - `plt.xlabel`,`plt.ylabel``plt.title`返回`matplotlib.text.Text`。
  - 使用`ax = plt.show()`,`type(ax)  NoneType`,因为`plt.show`不返回任何内容
- **`python 3.11`,`pandas 1.5.3`,`matplotlib 3.7.1`,`seaborn 0.12.2`中进行了测试**

[![在此输入图片描述][5]][5]

## `df`

```python
          Country Name                 Indicator Name       Valeur percents
0        United States              Population, total  320896618.0     100%
1        United States   Population, ages 0-14, total   61653419.0      19%
2        United States  Population, ages 15-64, total  212262832.0      66%
3        United States    Population, ages 65+, total   46980367.0      15%
4   Russian Federation              Population, total  144096870.0     100%
5   Russian Federation   Population, ages 0-14, total   24255306.0      17%
6   Russian Federation  Population, ages 15-64, total  100404879.0      70%
7   Russian Federation    Population, ages 65+, total   19436685.0      13%
8                Japan              Population, total  127141000.0     100%
9                Japan   Population, ages 0-14, total   16517168.0      13%
10               Japan  Population, ages 15-64, total   77547638.0      61%
11               Japan    Population, ages 65+, total   33076194.0      26%
12             Germany              Population, total   81686611.0     100%
13             Germany   Population, ages 0-14, total   10716271.0      13%
14             Germany  Population, ages 15-64, total   53720119.0      66%
15             Germany    Population, ages 65+, total   17250221.0      21%
16              France              Population, total   66624068.0     100%
17              France   Population, ages 0-14, total   12168975.0      18%
18              France  Population, ages 15-64, total   41837530.0      63%
19              France    Population, ages 65+, total   12617563.0      19%
英文:
  • It seems the dict must be the output of a DataFrame, which isn't shown in the OP.
  • Use .bar_label to add custom labels to the top of each bar. How to add value labels on a bar chart has a thorough explanation of the method.
    • Use the bar height (h), country, and container label, with Boolean indexing on df, to get the correct &#39;percents&#39; to annotate the bars.
    • The answers to this question do not demonstrate how to get the custom values for the bars.
  • Do not assign all lines to ax, as they do not return a matplotlib.axes. This overwrites ax, so ax.bar_label won't work.
    • plt.xlabel, plt.ylabel, and plt.title return matplotlib.text.Text.
    • With ax = plt.show(), type(ax) → NoneType because plt.show doesn't return anything.
  • Tested in python 3.11, pandas 1.5.3, matplotlib 3.7.1, seaborn 0.12.2
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# create the dataframe
data = {&#39;Country Name&#39;: {0: &#39;United States&#39;, 1: &#39;United States&#39;, 2: &#39;United States&#39;, 3: &#39;United States&#39;, 4: &#39;Russian Federation&#39;, 5: &#39;Russian Federation&#39;, 6: &#39;Russian Federation&#39;, 7: &#39;Russian Federation&#39;, 8: &#39;Japan&#39;, 9: &#39;Japan&#39;, 10: &#39;Japan&#39;, 11: &#39;Japan&#39;, 12: &#39;Germany&#39;, 13: &#39;Germany&#39;, 14: &#39;Germany&#39;, 15: &#39;Germany&#39;, 16: &#39;France&#39;, 17: &#39;France&#39;, 18: &#39;France&#39;, 19: &#39;France&#39;},
        &#39;Indicator Name&#39;: {0: &#39;Population, total&#39;, 1: &#39;Population, ages 0-14, total&#39;, 2: &#39;Population, ages 15-64, total&#39;, 3: &#39;Population, ages 65+, total&#39;, 4: &#39;Population, total&#39;, 5: &#39;Population, ages 0-14, total&#39;, 6: &#39;Population, ages 15-64, total&#39;, 7: &#39;Population, ages 65+, total&#39;, 8: &#39;Population, total&#39;, 9: &#39;Population, ages 0-14, total&#39;, 10: &#39;Population, ages 15-64, total&#39;, 11: &#39;Population, ages 65+, total&#39;, 12: &#39;Population, total&#39;, 13: &#39;Population, ages 0-14, total&#39;, 14: &#39;Population, ages 15-64, total&#39;, 15: &#39;Population, ages 65+, total&#39;, 16: &#39;Population, total&#39;, 17: &#39;Population, ages 0-14, total&#39;, 18: &#39;Population, ages 15-64, total&#39;, 19: &#39;Population, ages 65+, total&#39;},
        &#39;Valeur&#39;: {0: 320896618.0, 1: 61653419.0, 2: 212262832.0, 3: 46980367.0, 4: 144096870.0, 5: 24255306.0, 6: 100404879.0, 7: 19436685.0, 8: 127141000.0, 9: 16517168.0, 10: 77547638.0, 11: 33076194.0, 12: 81686611.0, 13: 10716271.0, 14: 53720119.0, 15: 17250221.0, 16: 66624068.0, 17: 12168975.0, 18: 41837530.0, 19: 12617563.0}}
df = pd.DataFrame(data)

# add the list of percent values to the dataframe, which assumes they&#39;re in the correct order (as they appear to be)
df[&#39;percents&#39;] = [&#39;100%&#39;, &#39;19%&#39;, &#39;66%&#39;, &#39;15%&#39;, &#39;100%&#39;, &#39;17%&#39;, &#39;70%&#39;, &#39;13%&#39;, &#39;100%&#39;, &#39;13%&#39;, &#39;61%&#39;, &#39;26%&#39;, &#39;100%&#39;, &#39;13%&#39;, &#39;66%&#39;, &#39;21%&#39;, &#39;100%&#39;, &#39;18%&#39;, &#39;63%&#39;, &#39;19%&#39;]

# create the plot
fig, ax = plt.subplots(figsize=(10, 5))
sns.barplot(data=df, x=&#39;Country Name&#39;, y=&#39;Valeur&#39;, hue=&#39;Indicator Name&#39;, palette=&quot;dark&quot;, ax=ax)

# customize the plot labels and title
plt.xlabel(&#39;&#39;)
plt.ylabel(&#39;Nombre de personnes&#39;, size=15)
plt.title(&#39;Etude de la r&#233;partition de la population&#39;, size=20)

# list of countries for selecting data from df
countries = [v.get_text() for v in ax.get_xticklabels()]  # countries = df[&#39;Country Name&#39;].unique() also works

# iterate through the axes bar containers
for c in ax.containers:
    
    # get the label of the current containers
    label = c.get_label()

    # use the height of the bar, country, and label name to get the corresponding percent for the container
    labels = [df.loc[df[&#39;Indicator Name&#39;].eq(label) &amp;
                     df[&#39;Country Name&#39;].eq(country) &amp;
                     df[&#39;Valeur&#39;].eq(h) , &#39;percents&#39;].iloc[0] if (h := v.get_height()) else &#39;&#39; for (v, country) in zip(c, countries)]
    
    # add the bar label with the custom labels
    ax.bar_label(c, labels=labels)

如何在分组的柱形图上显示自定义数值?

df

          Country Name                 Indicator Name       Valeur percents
0        United States              Population, total  320896618.0     100%
1        United States   Population, ages 0-14, total   61653419.0      19%
2        United States  Population, ages 15-64, total  212262832.0      66%
3        United States    Population, ages 65+, total   46980367.0      15%
4   Russian Federation              Population, total  144096870.0     100%
5   Russian Federation   Population, ages 0-14, total   24255306.0      17%
6   Russian Federation  Population, ages 15-64, total  100404879.0      70%
7   Russian Federation    Population, ages 65+, total   19436685.0      13%
8                Japan              Population, total  127141000.0     100%
9                Japan   Population, ages 0-14, total   16517168.0      13%
10               Japan  Population, ages 15-64, total   77547638.0      61%
11               Japan    Population, ages 65+, total   33076194.0      26%
12             Germany              Population, total   81686611.0     100%
13             Germany   Population, ages 0-14, total   10716271.0      13%
14             Germany  Population, ages 15-64, total   53720119.0      66%
15             Germany    Population, ages 65+, total   17250221.0      21%
16              France              Population, total   66624068.0     100%
17              France   Population, ages 0-14, total   12168975.0      18%
18              France  Population, ages 15-64, total   41837530.0      63%
19              France    Population, ages 65+, total   12617563.0      19%

huangapple
  • 本文由 发表于 2023年3月15日 19:01:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75743826.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定