这里利用Nathan Yau所著的《鲜活的数据:数据可视化指南》一书中的数据,学习画图。

数据地址:http://datasets.flowingdata.com/hot-dog-contest-winners.csv (用于普通柱形图)

http://datasets.flowingdata.com/hot-dog-places.csv (用于堆积柱形图和横向柱形图)

准备工作:先导入matplotlib和pandas,用pandas读取csv文件,然后创建一个图像和一个坐标轴

import pandas as pd
hot_dog=pd.read_csv(r"http://datasets.flowingdata.com/hot-dog-contest-winners.csv")
from matplotlib import pyplot as plt
fig,ax=plt.subplots()

让我们先看看第一个数据文件的前5行:

   Year                        Winner  Dogs eaten        Country  New record
0 1980 Paul Siederman & Joe Baldini 9.1 United States 0
1 1981 Thomas DeBerry 11.0 United States 0
2 1982 Steven Abrams 11.0 United States 0
3 1983 Luis Llamas 19.5 Mexico 0
4 1984 Birgit Felden 9.5 Germany 0

这个数据展示的是从1980年开始,每年吃热狗大赛的冠军,冠军吃掉热狗的数量,冠军的国籍,以及是否创新纪录(0表示没有破纪录,1表示创造了新纪录)。

让我们来画一个各年份冠军吃掉热狗数量的柱形图。

A. 普通柱形图

ax.bar(x,y)

import pandas as pd
hot_dog=pd.read_csv(r"http://datasets.flowingdata.com/hot-dog-contest-winners.csv")
from matplotlib import pyplot as plt
fig,ax=plt.subplots() ax.bar(hot_dog["Year"],hot_dog["Dogs eaten"])
ax.set_xlabel("Year") #设置x轴标签
ax.set_ylabel("Dogs Eaten") #设置y轴标签
ax.set_title("Hotdog game scores 1980-2010") #设置标题
ax.set_xlim(1979,2011) #设置x轴数据限值
plt.show() #显示图像

图像如下:

Matplotlib学习---用matplotlib画柱形图,堆积柱形图,横向柱形图(bar chart)-LMLPHP

如果我们需要把创造新纪录的年份区分开来呢?如何用不同的颜色进行表示?这时就需要写一个helper function,把各个年份应显示的颜色放入一个列表中。

import pandas as pd
hot_dog=pd.read_csv(r"http://datasets.flowingdata.com/hot-dog-contest-winners.csv")
from matplotlib import pyplot as plt
fig,ax=plt.subplots() def hotdog_color():
"创新纪录的为红色,其余为蓝色"
list=[]
for i in hot_dog["New record"]:
if i==1:
list.append("red")
else:
list.append("blue")
return list ax.bar(hot_dog["Year"],hot_dog["Dogs eaten"],color=hotdog_color())
ax.set_xlabel("Year") #设置x轴标签
ax.set_ylabel("Dogs Eaten") #设置y轴标签
ax.set_title("Hotdog game scores 1980-2010") #设置标题
ax.set_xlim(1979,2011) #设置x轴数据限值
plt.show() #显示图像

此时图像如下:

Matplotlib学习---用matplotlib画柱形图,堆积柱形图,横向柱形图(bar chart)-LMLPHP

这个颜色有点丑哈。。。对于配色问题,大家可以多尝试一下。

让我们再来看看另一个数据文件:

   2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010
0 25 50.0 50.5 44.5 53.5 49 54 66 59 68.0 54
1 24 31.0 26.0 30.5 38.0 37 52 63 59 64.5 43
2 22 23.5 25.5 29.5 32.0 32 37 49 42 55.0 37

这个文件很简短,展示的就是各年份冠亚季军所吃热狗的数量。

那么如何把各年份冠亚季军所吃热狗的数量用柱形图画出来呢?这时就要用到堆积柱形图了。

B. 堆积柱形图

思路:因为需要把冠亚季军所吃热狗的数量都展现出来,因此这个柱形图每个柱子的高度应该是冠亚季军所吃热狗数量的总和。如果在最上层展现冠军,那么先把冠亚季军所吃热狗数量的总和画出来,第二层是亚军,再画亚军所吃热狗的数量+季军所吃热狗的数量,用不同的颜色表示,这样第一次画的柱子下面就被第二次画的柱子所覆盖,第三层同理。

import pandas as pd
hot_dog=pd.read_csv(r"http://datasets.flowingdata.com/hot-dog-places.csv")
from matplotlib import pyplot as plt
fig,ax=plt.subplots() year=[int(i) for i in hot_dog.columns] #年份从header中提取
value=hot_dog.T.values #将冠亚季军所吃热狗的数量转化成matrix,也就是[[25,24,22],[50.0,31.0,23.5],...]
v1=[i[0]+i[1]+i[2] for i in value] #第一次画的柱形图y值为冠亚季军所吃热狗数量的总和
v2=[i[1]+i[2] for i in value] #第二次画的柱形图y值为亚军所吃热狗的数量+季军所吃热狗的数量
v3=[i[2] for i in value] #第三次画的柱形图y值为季军所吃热狗的数量 ax.bar(year,v1,color="green")
ax.bar(year,v2,color="red")
ax.bar(year,v3,color="blue")
ax.set(xlabel="Year",title="Hotdog game scores 2000-2010")
ax.text(1998,184,"(HDB)") #设置文字
ax.legend(["first place","second place","third place"]) #设置图例
plt.show()

图像如下:

Matplotlib学习---用matplotlib画柱形图,堆积柱形图,横向柱形图(bar chart)-LMLPHP

C. 横向柱形图(条形图)

把ax.bar( ) 换成ax.barh( )即可

(h是horizontal的意思)

import pandas as pd
hot_dog=pd.read_csv(r"http://datasets.flowingdata.com/hot-dog-places.csv")
from matplotlib import pyplot as plt
fig,ax=plt.subplots() year=[int(i) for i in hot_dog.columns] #年份从header中提取
value=hot_dog.T.values #将冠亚季军所吃热狗的数量转化成matrix,也就是[[25,24,22],[50.0,31.0,23.5],...]
v1=[i[0]+i[1]+i[2] for i in value] #第一次画的柱形图y值为冠亚季军所吃热狗数量的总和
v2=[i[1]+i[2] for i in value] #第二次画的柱形图y值为亚军所吃热狗的数量+季军所吃热狗的数量
v3=[i[2] for i in value] #第三次画的柱形图y值为季军所吃热狗的数量 ax.barh(year,v1,color="green")
ax.barh(year,v2,color="red")
ax.barh(year,v3,color="blue")
ax.set(ylabel="Year",title="Hotdog game scores 2000-2010")
ax.text(184,1998.3,"(HDB)") #设置文字
ax.legend(["first place","second place","third place"]) #设置图例
plt.show()

图像如下:

Matplotlib学习---用matplotlib画柱形图,堆积柱形图,横向柱形图(bar chart)-LMLPHP

04-08 21:35