英文:
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):
{'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.
[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 containerlabel
, with Boolean indexing ondf
, to get the correct'percents'
to annotate the bars. - The answers to this question do not demonstrate how to get the custom values for the bars.
- Use the bar height (
- Do not assign all lines to
ax
, as they do not return amatplotlib.axes
. This overwritesax
, soax.bar_label
won't work.plt.xlabel
,plt.ylabel
, andplt.title
returnmatplotlib.text.Text
.- With
ax = plt.show()
,type(ax) → NoneType
becauseplt.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 = {'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}}
df = pd.DataFrame(data)
# add the list of percent values to the dataframe, which assumes they're in the correct order (as they appear to be)
df['percents'] = ['100%', '19%', '66%', '15%', '100%', '17%', '70%', '13%', '100%', '13%', '61%', '26%', '100%', '13%', '66%', '21%', '100%', '18%', '63%', '19%']
# create the plot
fig, ax = plt.subplots(figsize=(10, 5))
sns.barplot(data=df, x='Country Name', y='Valeur', hue='Indicator Name', palette="dark", ax=ax)
# customize the plot labels and title
plt.xlabel('')
plt.ylabel('Nombre de personnes', size=15)
plt.title('Etude de la répartition de la population', size=20)
# list of countries for selecting data from df
countries = [v.get_text() for v in ax.get_xticklabels()] # countries = df['Country Name'].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['Indicator Name'].eq(label) &
df['Country Name'].eq(country) &
df['Valeur'].eq(h) , 'percents'].iloc[0] if (h := v.get_height()) else '' 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%
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论