python 中条形图顶部的值计数错位

Misplaced position of value counts on top of bar graph in python

我使用以下代码计算了数据框中的缺失值:

per_B = df.isna().mean().round(4) * 100

并使用以下代码绘制,NaN 值计数在顶部,但最后两个值计数位置放错了。

f, ax = plt.subplots(figsize=(20, 15))
for i,item in enumerate(zip(per_B.keys(), per_B.values)):
    if (item[1] > 0):
        ax.bar(item[0], item[1], label = item[0])
        ax.text(i - 0.40, item[1] + 0.5 , str(np.round(item[1],2)))    
ax.set_xticklabels([]) 
ax.set_xticks([]) 
plt.title('NaN Value percentage in Training Set B')
plt.ylim(0,115)
plt.ylabel('Percentage')
plt.xlabel('Columns')
plt.legend(loc='upper left')
plt.show()

谁能帮我解决代码中的错误,因为最后两列值计数放错地方了?

文本放错位置的原因是,即使您不绘制条形图,您也会让 i 递增(似乎有两个“项目”, item[1] <= 0 就在结束之前).您可以通过将 i 放在 for 之外并仅在绘制条形图时递增它来解决此问题。

所以,类似于:

i = 0
for key, value in zip(per_B.keys(), per_B.values)):
    if (value > 0):
        ax.bar(key, value, label=key)
        ax.text(i, value + 0.5, str(np.round(value, 2)), ha='center')
        i = i + 1 # increment the counter

可以使用 bar_label() 函数(matplotlib 3.4 中的新功能)以及创建仅包含非零元素的 per_B 的子集来简化代码:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# first create some test data
data = np.random.rand(1000)
data[np.random.randint(0, 1000, 2000)] = np.nan
df = pd.DataFrame(data.reshape(-1, 10), columns=[*'abcdefghij'])
df['g'] = 1 # no NaNs in columns 'g' and 'h'
df['h'] = 1

per_B = df.isna().mean().round(4) * 100

per_B_nonzeo = per_B[per_B > 0] # subset containing all the nonzero vlaues

fig, ax = plt.subplots()
for key, value in per_B_nonzeo.iteritems():
    bar = ax.bar(key, value, label=key)
    ax.bar_label(bar, labels=[f'{value:.2f}'])
plt.show()