我有一个这样的数据框:
platform count
release_year
1996 PlayStation 138
1997 PlayStation 170
1998 PlayStation 155
1999 PC 243...
现在我想在相应的条形图中使用平台名称绘制水平条形图,使其看起来像这样:
我该怎么做?
答案 0 :(得分:7)
一旦找到每个平台的百分比,就会输入data.csv
文件:
Platform,Percent
Nintendo,34
PC,16
Playstation,28
Xbox,22
这是代码:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("data.csv", index_col=0)
df.plot(kind="barh", legend=False, width=0.8)
for i, (p, pr) in enumerate(zip(df.index, df["Percent"])):
plt.text(s=p, x=1, y=i, color="w", verticalalignment="center", size=18)
plt.text(s=str(pr)+"%", x=pr-5, y=i, color="w",
verticalalignment="center", horizontalalignment="left", size=18)
plt.axis("off")
# xticks & yticks have empty lists to reduce white space in plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.savefig("data.png")
答案 1 :(得分:2)
不确定您是希望它位于百分比%还是计数本身。这取决于你自己决定。 但是,首先使用以下方法将数据帧转换为列表:
count = df["count"].tolist()
platform = df["platform"].tolist()
我不会专注于此。你可以从
找到一些帮助一旦你得到以下列表,
count = ['138','170','155','243','232']
platform =['PlayStation','PlayStation','PlayStation','PC','PlayStation']
注意:以上两个是条形图中的文字标签。
以下是完整的代码:
import matplotlib.pyplot as plt
from numpy.random import rand
from numpy import arange
count = ['138','170','155','243','232']
platform =['PlayStation','PlayStation','PlayStation','PC','PlayStation']
def autolabel(rects):
# attach some text labels
for ii,rect in enumerate(rects):
width = int(rect.get_width())
height = rect.get_height()
print(height,width)
yloc1=rect.get_y() + height /2.0
yloc2=rect.get_y() + height /2.0
if (width <= 5):
# Shift the text to the right side of the right edge
xloc1 = width + 1
yloc2=yloc2+0.3
# Black against white background
clr = 'black'
align = 'left'
else:
# Shift the text to the left side of the right edge
xloc1 = 0.98*width
# White on blue
clr = 'white'
align = 'right'
yloc1=rect.get_y() + height /2.0
print(xloc1,yloc1,yloc2)
ax.text(xloc1,yloc1, '%s'% (count[ii]),horizontalalignment=align,
verticalalignment='center',color=clr,weight='bold',
clip_on=True)
ax.text(5,yloc2, '%s'% (platform[ii]),horizontalalignment='left',
verticalalignment='center',color=clr,weight='bold',
clip_on=True)
val = [138,170,155,243,232]
print(val)# the bar lengths or count in your case
pos = [ 1996 , 1997, 1998, 1999, 2000] # the bar centers on the y axis
print(pos)
fig = plt.figure()
ax = fig.add_subplot(111)
rects = ax.barh(pos,val, align='center',height=0.4)
print(rects)
autolabel(rects)
ax.set_ylabel('Year')
ax.set_xlabel('Count')
ax.set_title('horizontal bar chart')
ax.grid(False)
plt.savefig("horizontal.png")
plt.show()
你非常感兴趣的部分:
def autolabel(rects):
# attach some text labels
for ii,rect in enumerate(rects):
width = rect.get_width()
height = rect.get_height()
yloc1=rect.get_y() + height /2.0
yloc2=rect.get_y() + height /2.0
if (width <= 5):
# Shift the text to the right side of the right edge
xloc1 = width + 1
yloc2=yloc2+0.3
# Black against white background
clr = 'black'
align = 'left'
else:
# Shift the text to the left side of the right edge
xloc1 = 0.98*width
# White on blue
clr = 'white'
align = 'right'
yloc1=rect.get_y() + height /2.0
ax.text(xloc1,yloc1, '%s'% (count[ii]),horizontalalignment=align,
verticalalignment='center',color=clr,weight='bold',
clip_on=True)
ax.text(5,yloc2, '%s'% (platform[ii]),horizontalalignment='left',
verticalalignment='center',color=clr,weight='bold',
clip_on=True)
1) ii 变量来自枚举,其值为0到5.用于迭代我们的列表count
和platform
2)为什么函数中有if / else语句?这适用于宽度太小的情况。假设从val = [138,170,155,243,232]
获得的第一个宽度减少到5,即val = [5,170,155,243,232]
,在这种情况下,输出将是。{/ p>
我们基本上做的是为ax.text()
个函数提供xloc(x坐标)和yloc(y坐标)值。
ax.text(xloc1,yloc1, '%s'% (count[ii]),horizontalalignment=align,
verticalalignment='center',color=clr,weight='bold',
clip_on=True)
ax.text(5,yloc2, '%s'% (platform[ii]),horizontalalignment='left',
verticalalignment='center',color=clr,weight='bold',
clip_on=True)
功能参数
text(x,y,s,fontdict = None,withdash = False,** kwargs)
x,y:数据坐标
s:字符串,而其他两个是可选的。
如果宽度<&lt;然后稍微增加yloc。所以文字略高一点。同时改变xloc。也将颜色改为黑色。否则颜色会变白。
如果您更改这些值并查看输出如何变化以便更好地理解它,那么它将最佳。