我有一个seaborn计数图,但我需要每个条上方的值而不是颜色条。我的输入是pandas数据帧。
ax = sns.countplot(x="variable", hue="value", data=pd.melt(dfs))
这里dfs有不同列的许多条目。
例如,蓝色条上方的“男人”,棕色条上方的“女人”和绿色条上方的“孩子”而不是颜色描述。
有时候更容易找到调整seaborn的方法,而是直接使用matplotlib并从头开始构建图表。
在这里,我们可以假设有一个名为counts
的数据帧
hue c m w
class
A 20 31 29
B 40 112 63
C 85 203 117
其中索引是沿x轴的位置,列是不同的色调。在下文中,groupedbarplot
是一个将这样的数据帧作为输入并将条形图绘制为组的函数,另外还为它们中的每一个添加标签。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(42)
def groupedbarplot(df, width=0.8, annotate="values", ax=None, **kw):
ax = ax or plt.gca()
n = len(df.columns)
w = 1./n
pos = (np.linspace(w/2., 1-w/2., n)-0.5)*width
w *= width
bars = []
for col, x in zip(df.columns, pos):
bars.append(ax.bar(np.arange(len(df))+x, df[col].values, width=w, **kw))
for val, xi in zip(df[col].values, np.arange(len(df))+x):
if annotate:
txt = val if annotate == "values" else col
ax.annotate(txt, xy=(xi, val), xytext=(0,2),
textcoords="offset points",
ha="center", va="bottom")
ax.set_xticks(np.arange(len(df)))
ax.set_xticklabels(df.index)
return bars
df = pd.DataFrame({"class" : np.random.choice(list("ABC"), size=700, p=[.1,.3,.6]),
"hue" : np.random.choice(["m", "w" ,"c"], size=700, p=[.5,.3,.2])})
counts = df.groupby(["class", "hue"]).size().unstack()
groupedbarplot(counts, annotate="col")
plt.show()
我们也可以直接标记值,groupedbarplot(counts, annotate="values")