这里只讲数据分析常用的图形绘制,至于复杂的图形不在本篇讨论范围,讲到的几个图形基本满足数据分析过程的要求,至于汇报材料或者其他的高质量图形,以后再另外写关于ggplot2的简单使用。
python的绘图工具主要是matplotlib,这里不讲复杂的使用,只讲简单的使用。
使用matplotlib绘图有两种方法:
1.matplotlib绘图,指定参数data=DataFrame或Series
2.pandas对DataFrame和Series做了处理,它们本身有plot的方法
1.使用matplotlib绘图,如果用过MATLAB的朋友对这个不陌生。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import DataFrame, Series
from numpy.random import randn,rand
import matplotlib as mpl
from matplotlib.pyplot import savefig
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
# 1.先创建一个画布
fig = plt.figure()
# 2.然后创建图形矩阵
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
# 3.查看画布
fig
# 4.单独绘制曲线
plt.plot(randn(50).cumsum(), 'k--')
# 5.在刚才创建的图形矩阵上画图
# 5.1.直方图
ax1.hist(randn(100), bins = 20, color = 'k', alpha = 0.3)
# 5.2.散点图
ax2.scatter(np.arange(30), np.arange(30)+3*randn(30))
# 5.3.线图(默认)
ax3.plot(randn(50).cumsum(),'k--')
# 6.将画好的图形显示出来
fig
# 或者
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
前面的代码是先创建画布然后创建图形矩阵,有人嫌麻烦,于是有了下面的代码。
# 创建图形矩阵的快捷函数
# sharex,sharey 共享x,y轴,也就是刻度线是一样的
fig, axes = plt.subplots(2,2, sharex = True, sharey = True)
for i in range(2):
for j in range(2):
axes[i,j].hist(randn(500), bins=50,
color='k', alpha = 0.5)
plt.subplots_adjust(wspace = 0,hspace=0)
fig
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
# 图形的属性
1.color:颜色
1.1 r:红色
1.2 b:蓝色
1.3 g:绿色
1.3 y:黄色
2.数据标记markder
2.1 o:圆圈
2.2 .:圆点
2.2 d:棱形
3.线型linestyle
3.1 没有参数的话就是默认画点图
3.2 --:虚线
3.3 -:实线
4.透明度
alpha
5.大小
size
6.网格线
plt.grid(True,color='g',linestyle='-',linewidth='2')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
# 区域填充
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(0,5*np.pi,1000)
y1=np.sin(x)
y2=np.sin(2*x)
plt.plot(x,y1)
plt.plot(x,y2)
# 填充
plt.fill(x,y1,'b',alpha=0.3)
plt.fill(x,y2,'r',alpha=0.3)
# 只填充相交区域
fig=plt.figure()
ax=plt.gca()
ax.plt(x,y1,x,y2,color='black')
ax.fill_between(x,y1,y2,facecolor='blue')
ax.fill_between(x,y1,y2,where=y1>y2,facecolor='yellow',interpolate=True)
ax.fill_between(x,y1,y2,where=y2>y1,facecolor='green',interpolate=True)
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
# 样式
plt.style.use('ggplot')
# 打印plt支持的样式
print(plt.style.available)
- 1
- 2
- 3
- 4
- 5
# 直方图与二维直方图
# 使用plt方式
import numpy as np
import matplotlib.pyplot as plt
# normed 标准化指定是显示频率还是频数
mu = 100
sigma = 20
x = mu + sigma * np.random.randn(2000)
plt.hist(x, bins=10,color='red',normed=True)
plt.hist(x, bins=50,color='green',normed=False)
plt.show()
# 二维直方图
x = np.random.randn(1000)+2
y = np.random.randn(1000)+3
plt.hist2d(x, y, bins=40)
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
# 积分图
# 其实是绘制多边形图实现积分图
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon #多边形
import numpy as np
def func(x):
return -(x-2)*(x-8)+40
x=np.linspace(0,10)
y=func(x)
fig.ax=plt.subplot()
plt.plot(x,y,'r',linewidth=2)
a,b=2,9
ax.set_xticks([a,b])
# ax.set_yticks([])
ax.set_xticklabels(['$a$','$b$'])
# 绘制积分区域的多边形点位置
ix=np.linspace(a,b)
iy=func(ix)
ixy=zip(ix,iy)
verts=[(a,0)]+list(ixy)+[(b,0)]
poly=Ploygen(verts,facecolor='0.9',egdcolor='0.1')
ax.add_patch(poly)
plt.figtext(0.9,0.05,'$x$')
plt.figtext(0.1,0.9,'$y$')
x_mathch=(a+b)*0.4
y_match=30
plt.text(x_match,y_match,
r'$inta^b (-(x-2)*(x-8)+40)dx$',fontsize=20)
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
# 公式
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_xlim(1,7)
ax.set_ylim(1,5)
ax.text(2,4,r"$ \alpha_i \pi \lambda \omega $",
size=25)
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
plt.plot(randn(30).cumsum(),'b.--')
- 1
# 设置标题,轴刻度,轴标签,以及刻度标签
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(randn(1000).cumsum())
ticks = ax.set_xticks([0,250,500,750,1000]) #x轴刻度
labels = ax.set_xticklabels(['one','tow','three','four','five'],
rotation=30, fontsize='small') #x轴刻度名称
ax.set_title('my first matplotlib plot') #标题
ax.set_xlabel('stages') #x轴标题
fig
# 添加图例
# 也是在同一幅图中绘制多条线的方法
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(randn(1000).cumsum(), 'k',label='one')
ax.plot(randn(1000).cumsum(),'k--', label='two')
ax.plot(randn(1000).cumsum(), 'k.',label = 'three')
# 图例放置的位置
ax.legend(loc='best')
# ax.legend(loc=1) # 1,2,3,4表示图的4个角落
fig
# 保存图片
fig.savefig('pd_fig.png')
# 注解,以及subplot上绘图
from datetime import datetime
data = pd.read_csv('spx.csv',index_col = 0,parse_dates=True)
spx=data['SPX']
data.columns
data.head()
fig=plt.figure()
ax = fig.add_subplot(1,1,1)
spx.plot(ax=ax, style='k--')
crisis_data=[
(datetime(2007,10,11),'peak of bull market'),
(datetime(2008,3,12),'bear strarns fails'),
(datetime(2008,9,15),'lehman bankruptcy')
]
for date,label in crisis_data:
ax.annotate(label, xy=(data,spx.asof(date)+50),
xytext=(date,spx.asof(date)+200),
arrowprops=dict(facecolor='black'),
verticalalignment='top')
# 轴刻度范围
ax.set_xlim(['1/1/2007','1/1/2011'])
ax.set_ylim([600,800])
ax.set_title('import dates in 2008-2009 financial crisis')
fig
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
批量保存图片
如果只有一张图片,这没什么好说的,但是如果要对每个维度绘图,然后保存图片呢。
下面的批量保存的伪代码
for _ in all_need_plot:
fig = plt.figure()
ax=fig.add_subplot(111)
sub_data[years].plot(ax=ax, style='o-',title='%s 月销量趋势图'%lev3)
file = r'E:\服装预测\销量趋势-%s.jpg' %lev3
savefig(file)
time.sleep(0.5) # 注意这里要暂停一下,不然会出问题的
plt.close() # 最后记得关闭句柄,再画下一张图
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
前面说过,既可以用matplotlib来绘图,Series和DataFrame本身也封装有绘图的函数。下面是一些常用的图形。
作图函数名 | 功能 | 模块 |
---|---|---|
plot() | 折线图,点图 | matplotlib 和 pandas |
pie() | 饼图 | matplotlib 和 pandas |
hist() | 直方图,条形图 | matplotlib 和 pandas |
boxplot() | 箱线图 | pandas |
plot(loyg=True) | y轴的对数图形 | pandas |
plot(yerr=True) | 误差条形图 | pandas |
pandas简单画图
# 1.matplotlib的方法
import matplotlib.pyplot as plt
plt.plot(x,y,S)
# S是图形选项,包括颜色,样式,图形的类型,具体的参数和前面的一样。
# 2.pandas的方法
D.plot(kind='图形类型')
# D是DataFrame或者Series,默认以index为横坐标,
# 每列数据为纵坐标自动绘图,也就是每列数据绘制一个图形。
# kind=
# line :线
# bar :条形图
# barh,hist :直方图
# box :箱线图
# kde :密度图
# area :面积图
# pie :饼图
# 除了kind参数外,也能接受plt.plot()中的参数。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
常用的图形
# 1.线形图(默认)
s = Series(randn(10).cumsum(),
index=np.arange(0,100,10))
s.plot(style='ko--')
#如果是数据框,则每一列画一条线
df = DataFrame(randn(10,4).cumsum(0),columns=['a','b','c','d'],index=np.arange(0,100,10))
df.plot()
# 2.柱状图
# 柱状图是对每一个数字画图,如果有多个数字就画多条柱子
# 也就是说,柱状图需要给定柱子的高度。注意这和直方图是不一样的,
# 直方图会自己计数,然后绘图,如果画得比较细,就是密度曲线了
fig,axes = plt.subplots(2,1)
data = Series(np.random.rand(16),index=list('abcdefghijklmnop'))
data.plot(kind='bar',ax=axes[0])
data.plot(kind='bar',ax=axes[1])
fig
df = DataFrame(np.random.rand(6,4),
index='one','two','three','four','five','six'],
name='Genus'))
df
# 每行画一个族柱,有多少行就有多少族柱
df.plot(kind='bar')
# 2.2堆积的柱状图
df.plot(kind='bar',stacked=True,alpha=0.5)
tips = pd.read_csv('tips.csv')
tips.head()
party_counts=pd.crosstab(tips.size,tips.day)
party_counts
party_pcts=party_counts.div(party_counts.sum(1),axis=0)
party_pcts
party_pcts.plot(kind='bar',stacked=True)
# 3.直方图和密度图
# 注意和前面的柱状图的区别,直方图可以自动对给定的区间计数,绘制高度
tips['tip_pct']=tips['tip']/tips['total_bill']
tips['tip_pct'].hist(bins=50)
# 4.密度曲线
tips['tip_pct'].plot(kind='kde')
# 将两幅图画在一起
comp1=np.random.normal(0,1,size=200)
comp2=np.random.normal(10,2,size=200)
values=Series(np.concatenate([comp1,comp2]))
values
values.hist(bins=100, alpha=0.3, color='k',normed=True)
values.plot(kind='kde',style='k--')
# 5.散布图,散点图
macro = pd.read_csv('macrodata.csv')
data = macro[['cpi','m1','tbilrate','unemp']]
trans_data = np.log(data).diff().dropna()
trans_data[-5:]
trans_data.tail()
plt.scatter(trans_data['m1'],trans_data['unemp'])
plt.title('change in log %s vs log %s' %('m1','unemp'))
plt.show()
# 5.2.散点图矩阵
pd.scatter_matrix(trans_data,diagonal='kde', color='k', alpha=0.3)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
python画图,最好的还是seaborn,绘制配色漂亮的统计图形,其分组,分面,统计等,堪比ggplot啊