python数据可视化之matplotlib

python数据可视化之matplotlib

基本绘制图形

1
matplotlib.use('TkAgg')

注意,使用这行代码可以在鼠标移动的时候显示坐标信息

或者File -> Settings -> Tools -> Python Scientific -> 去掉Show plots in tool window勾选

绘制直线图

1
2
3
4
import matplotlib.pyplot as plt
# 将(0,1) 点和(2,4)连起来
plt.plot([0,2],[1,4])
plt.show()

效果如下

绘制折线图

1
2
3
4
5
6
import matplotlib.pyplot as plt
x = [1,2,3,4,5]
y = [1,4,9,16,25]
plt.plot(x,y)
plt.savefig("1-2.png")
plt.show()

设置样式

设置标签文字和线条粗细

在上面的实例直线结果不够完美,我们可以对线条样式进行灵活设置。例如:可以设置线条的粗细,设置文字等等

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt
x = [1,2,3,4,5]
y = [1,4,9,16,25]
plt.plot(x,y,linewidth =5)
plt.title("Numbers",fontsize = 24)
plt.xlabel("x",fontsize = 14)
plt.ylabel("y",fontsize = 14)
plt.savefig("2-1.png")
plt.show()

当标题为中文,那么会出现乱码,可以在上面加上一行代码

1
2
plt.rcParams["font.sans-serif"]=["SimHei"]
plt.title("折线图",fontsize = 24)

绘制曲线

一元二次方程

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt
# 默认每个1个点取一个数
x = range(-100,100)
# i**2 说明是 i 的平方
y = [i**2 for i in x]
# 绘制一元二次方程
plt.plot(x,y)
plt.savefig("3-1.png")
plt.show()

绘制正弦余弦曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import matplotlib.pyplot as plt
# numpy库封装了很多计算的api,就不需要我们自己算了
import numpy as np
# 生成0-10之间100个等差数
x = np.linspace(0,10,100)
sin_x = np.sin(x)
# 绘制正弦曲线
plt.plot(x,sin_x)
cos_x = np.cos(x)
plt.plot(x,cos_x)
# 默认第一个为蓝色第二个为橙黄色,和matlab不一样
#这里不需要hold on就可以在同一张图上显示多条曲线
plt.savefig("3-2.png")
plt.show()

subplot的使用

subplot()函数将画布分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import matplotlib.pyplot as plt
import numpy as np
# 把画布分为区域,把图画分配到画布的指定区域
# linspace 是从1-10 均匀取100个点
x = np.linspace(1,10,100)
sin_x = np.sin(x)
cos_x = np.cos(x)
# 讲画布分为2行2列,将图画分配到画布的1区域
plt.subplot(2,2,1)
plt.plot(x,sin_x)
# 将图画分配到画布的4区域
plt.subplot(2,2,4)
plt.plot(x,cos_x)
plt.show()

通过 plt.xlim()和plt.ylim()修改坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import matplotlib.pyplot as plt
import numpy as np
# 把画布分为区域,把图画分配到画布的指定区域
x = np.linspace(1,10,100)
sin_x = np.sin(x)
cos_x = np.cos(x)
# 讲画布分为2行2列,将图画分配到画布的1区域
plt.subplot(2,2,1)
# 通过 plt.xlim()和plt.ylim()修改坐标
plt.xlim(-5,20)
plt.ylim(-5,5)
plt.plot(x,sin_x)
plt.subplot(2,2,4)
plt.plot(x,cos_x)
plt.savefig("4-2.png")
plt.show()

绘制散点图

利用散点图函数scatter 可以绘制随机点,该函数需要接收x坐标和y坐标的序列

1
2
3
4
5
6
7
import matplotlib.pyplot as plt
import numpy as np
x= np.linspace(0,10,100)
sin_x = np.sin(x)
plt.scatter(x,sin_x)
plt.savefig("5-1")
plt.show()

也可以通过

1
plt.plot(x,sin_x,'o')

这行代码来画出散点图。

从上面的示例可以看出,使用plot 绘制和使用scatter绘制出来的图形是没有区别的,但是使用plot绘制图形的速度优于scatter,所以如果画一堆点,而且点的形式没有差别,那么用plot即可,如果点的形式(大小,颜色)有差别,则必须使用scattter()函数

绘制大小颜色不同的散点图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import numpy as np
# 创建x
np.random.seed(0)#可以让每次取的随机点都相同
x = np.random.rand(100)#rand()中的数字就是随机点的个数
y = np.random.rand(100)
# 生成点的10种不同的大小
size = np.random.rand(10)*500
# 如果这里color有1000种,或10种
# 那么会报错。所以点的个数要和个数相同,但size个数可以不相同,
color = np.random.rand(100)
# s表示点的大小,c代表点的颜色,alpha表示透明度
plt.scatter(x,y,s=size,c=color,alpha=0.7)
plt.savefig("5-2")
plt.show()
  • 注意:
    • 点的个数和颜色的个数一定要相同,多一点少一点都不行
    • 点的个数和点的大小的个数可以不相同,如果点的个数大于大小的个数,则会循环获取大小

绘制不同样式和颜色的线条

格式化字符

字符 描述
‘-‘ 实线样式
‘—‘ 短横线样式
‘-.’ 点划线样式
‘:’ 虚线样式
‘.’ 点标记
‘,’ 像素标记
‘o’ 圆标记
‘v’ 倒三角标记
‘^’ 正三角标记
‘1’ 下箭头标记
‘2’ 上箭头标记
‘3’ 左箭头标记
‘4’ 右箭头标记
‘s’ 正方形标记
‘p’ 五边形标记
‘*’ 星形标记
‘h’ 六边形标记 1
‘H’ 六边形标记 2
‘+’ 加号标记
‘x’ X 标记
‘D’ 菱形标记
‘d’ 窄菱形标记
‘_’ 水平线标记

以下是颜色的缩写:

字符 颜色
‘b’ 蓝色
‘g’ 绿色
‘r’ 红色
‘c’ 青色
‘m’ 品红色
‘y’ 黄色
‘k’ 黑色
‘w’ 白色

不同种类的不同颜色的线

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
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(0,10,50)
plt.plot(x,x+0,'-g') #实线 绿色
plt.plot(x,x+2,'--c') #虚线 浅蓝色
plt.plot(x,x+4,'-.k') #点划线 黑色
plt.plot(x,x+6,'-r') #实线 红色
plt.plot(x,x+8,'o') #点 默认是蓝色
plt.plot(x,x+10,'x') #叉叉 默认是蓝色
plt.plot(x,x+12,'d') #砖石
plt.plot(x,x+14,':') #虚线
plt.plot(x,x+16,',') #像素
plt.plot(x,x+18,'o') # 点标记
plt.plot(x,x+20,'v') # 倒三角
plt.plot(x,x+22,'^') #正三角
plt.plot(x,x+24,'1') #下箭头
plt.plot(x,x+26,'2') # 上箭头
plt.plot(x,x+28,'3') # 左箭头
plt.plot(x,x+30,'4') #右箭头
plt.plot(x,x+32,'s') #正方形
plt.plot(x,x+34,'p') #五边形
plt.plot(x,x+36,'*') #星形
plt.plot(x,x+38,'h') #六边形标记1
plt.plot(x,x+40,'H') #六边形标记2
plt.plot(x,x+42,'+') #加号标记
plt.plot(x,x+44,'x') #x标记
plt.plot(x,x+46,'D') #菱形标记
plt.plot(x,x+48,'d') #窄菱形标记
plt.plot(x,x+50,'_') #水平线标记
plt.savefig("6-1")
plt.show()

不同种类不同颜色的线并添加图例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import numpy as np
#不同种类不同颜色的线并添加图例
x=np.linspace(0,10,100)
plt.plot(x,x+0,'-g',label='-g') #实线 绿色
plt.plot(x,x+1,'--c',label='--c') #虚线 浅蓝色
plt.plot(x,x+2,'-.k',label='-.k') #点划线 黑色
plt.plot(x,x+3,'-r',label='-r') #实线 红色
plt.plot(x,x+4,'o',label='o') #点 默认是蓝色
plt.plot(x,x+5,'x',label='x') #叉叉 默认是蓝色
plt.plot(x,x+6,'dr',label='dr') #砖石 红色
#添加图例右下角lower right 左上角upper left,默认是右上角
#fancybox:边框 framealpha:透明度 shadow: 阴影 borderpad:边框宽度
plt.legend(loc='lower right',fancybox=True,framealpha=1,shadow=True,borderpad=1)
plt.show()

绘制柱状图

使用bar函数可以绘制柱状图。柱状图需要水平的x坐标值,以及每一个坐标值对应的y的坐标值,从而形成柱状的图。柱状图主要用来纵向对比和横向对比的,例如,根据年份对销售额进行纵向对比,x坐标值就表示年份,y坐标值表示销售数据

需要注意的是bar函数的宽度并不是像素宽度。bar函数会根据二维坐标系的尺寸,以及x坐标值的多少,自动确定每一个柱的宽度,而width指定的宽度就是这个标准柱宽度的倍数。该参数值可以是浮点数,如0.5,表示柱的宽度是标准宽度的0.5倍。

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt
x = [1980,1985,1990,1995]
x_label = ['1980年','1985年','1990年','1995年']
y = [1000,2000,3000,4000]
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.bar(x,y,3)#width 修改柱的宽度
plt.xticks(x,x_label)# 修改x轴的索引值
plt.savefig("7-1")
plt.show()

barh函数的使用(水平柱状图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x = np.arange(5)
y = np.random.randint(-5,5,5)
# 把画布分割成一行两列
plt.subplot(1,2,1)
v_bar = plt.bar(x,y)
# 在第一列的画布中 0 位置画一条蓝线
plt.axhline(0,color = 'blue',linewidth = 2)
plt.subplot(1,2,2)
# barh 函数,把y和x轴对换,竖着方向为x轴
h_bar =plt.barh(x,y,color = 'red')
# 在第一列的画布中 0 位置画一条蓝线
plt.ayhline(0,color = 'blue',linewidth = 2)
plt.savefig("7-2")
plt.show()

对柱体设置不同颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x = np.arange(5)
y = np.random.randint(-5,5,5)
# 在第一列的画布中 0 位置画一条蓝线
plt.axhline(0,color = 'blue',linewidth = 2)
v_bar = plt.bar(x,y,color = 'blue')
# 对y值大于0的设置为蓝色,小于0的柱体设置为绿色
# zip把v_bar 和y 组合到一起,通过 y的值修改bar的颜色
for bar,height in zip(v_bar, y):
if height< 0 :
bar.set(color = 'green')

plt.show()

柱状图示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"]=["SimHei"]
movie_name = ['千与千寻','玩具总动员4','黑衣人:全球通缉']
movie_number1 = [7458,4013,1673]
movie_number2 = [5453,1840,1080]
movie_number3 = [4843,2345,1890]
x = np.arange(len(movie_name))
width=0.3
plt.bar(x,movie_number1,alpha=0.5,width = 0.3,label=movie_name[0])
plt.bar([i+width for i in x],movie_number2,alpha=0.5,width = 0.3,label=movie_name[1])
plt.bar([i+width*2 for i in x],movie_number3,alpha=0.5,width = 0.3,label=movie_name[2])
x_label = ['第{}天'.format(i+1) for i in x]
plt.xticks([i+width for i in x],x_label)
plt.ylabel("票房")
# 添加图例
plt.legend()
# 添加标题
plt.title('电影票房')
plt.savefig("7-4")
plt.show()

绘制饼状图

pie函数可以绘制饼状图,饼图主要是用来呈现比例的。只要传入比例数据即可。

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
#导入模块
import matplotlib.pyplot as plt
import numpy as np
#准备男、女的人数及比例
man=71351
woman=68187
man_perc=man/(woman+man)
woman_perc=woman/(woman+man)
#添加名称
labels=['男','女']
#添加颜色
colors=['blue','red']
#绘制饼状图 pie
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
# labels 名称 colors:颜色,explode=分裂,即中间有缝隙 autopct显示百分比
# 让三个变量返接受饼状图的三个参数
paches,texts,autotexts=plt.pie([man_perc,woman_perc],labels=labels,colors=colors,explode=(0,0.05),autopct='%0.1f%%')

#设置饼状图中的字体颜色
for text in autotexts:
text.set_color('white')

#设置字体大小
for text in texts+autotexts:
text.set_fontsize(20)
plt.show()

绘制直方图

直方图与柱状图的分格类似,都是由若干个柱组成,但直方图和柱状图的含义却有很大的差异。直方图是用来观察分布状态的,而柱状图是用来看每一个X坐标对应的Y的值的。也就是说,直方图关注的是分布,并不关心具体的某个值,而柱状图关心的是具体的某个值。使用hist函数绘制直方图。

使用random函数生成1000个正态分布的随机数,使用hist函数绘制这1000个随机数的分布状态

1
2
3
4
5
6
7
8
9
#导入模块
import numpy as np
import matplotlib.pyplot as plt
#频次直方图,均匀分布
#正态分布
x=np.random.randn(1000)
#画正态分布图
plt.hist(x,bins=100) #装箱的操作,将10个柱装到一起及修改柱的宽度
plt.show()

使用normal 函数生成1000 个正态分布的随机数,使用hist 函数绘制这100 个随机数的分布状态

使用np.random.normal()指定期望和均值的正态分布

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
#几个直方图画到一个画布中,第一个参数期望 第二个均值
x1=np.random.normal(0,0.8,1000)
x2=np.random.normal(-2,1,1000)
x3=np.random.normal(3,2,1000)
#参数分别是bins:装箱,alpha:透明度
kwargs=dict(bins=100,alpha=0.4)
# 传入字典的时候,用**
plt.hist(x1,**kwargs)
plt.hist(x2,**kwargs)
plt.hist(x3,**kwargs)
plt.savefig("9-1")
plt.show()

绘制等高线图和三维图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#导入模块
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-10,10,100)
y=np.linspace(-10,10,100)
#计算x和y的相交点a
X,Y=np.meshgrid(x,y)
# 计算Z的坐标
Z=np.sqrt(X**2+Y**2)
plt.contourf(X,Y,Z) #加了f之后,画出来的图象就是有颜色的
#plt.contour(X,Y,Z)不加f画出来的只有线
# 颜色越深表示值越小,中间的黑色表示z=0.
plt.savefig("10-1")
plt.show()

使用pyplot绘制等高线图

使用pyplot包和Matplotlib绘制三维图。

1
2
3
4
5
6
7
8
9
10
11
12
import matplotlib.pyplot as plt
#导入3D包
from mpl_toolkits.mplot3d import Axes3D
#创建X、Y、Z坐标
X=[1,1,2,2]
Y=[3,4,4,3]
Z=[1,100,1,1]
fig = plt.figure()
# 创建了一个Axes3D的子图放到figure画布里面
ax = Axes3D(fig)
ax.plot_trisurf(X, Y, Z)
plt.show()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
# matplotlib.use('TkAgg')
# X,Y value
X = np.arange(-4,4,0.25)
Y = np.arange(-4,4,0.25)
X,Y = np.meshgrid(X,Y)
R = np.sqrt(X**2+Y**2)
Z = np.sin(R)
ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap = plt.get_cmap('rainbow'))
# zdir就是从那个维度开始投影,这里是z向下看,-2就是投影到z=-2平面
ax.contourf(X,Y,Z,zdir='z',offset=-2,cmap = plt.get_cmap('rainbow'))
# 规定z的坐标范围是(-2,2)
ax.set_zlim(-2,2)
plt.show()

rstride = 5,cstride = 5的效果

旋转抛物面

z = x^2^ +y^2^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
# 简单方法画出漂亮的圆锥体(底面在上,顶点在原点)
# 生成圆锥数据,底面半径为1,高度为1,其余的情形留待发挥
# 先根据极坐标方式生成数据
u = np.linspace(0, 2 * np.pi, 50) # linspace的功能用来创建等差数列
v = np.linspace(0, np.pi, 50)
# 数据转化为平面坐标数据
x = np.outer(np.cos(u), np.sin(v)) # outer(a,b) 外积:a的每个元素乘以b的每个元素,二维数组
y = np.outer(np.sin(u), np.sin(v))
z = x ** 2 + y ** 2 # 圆锥体的高
# Plot the surface
ax.plot_surface(x, y, z, cmap=plt.get_cmap('rainbow'))
plt.show()

修改x,y,z可以得到y = x^2^ +z^2^

x =y^2^ +z^2^

抛物面

圆柱面图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
# 生成圆柱数据,底面半径为r,高度为h。
# 先根据极坐标方式生成数据
u = np.linspace(0, 2 * np.pi, 50) # 把圆分按角度为50等分
h = np.linspace(0, 1, 20) # 把高度1均分为20份
x = np.outer(np.sin(u), np.ones(len(h))) # x值重复20次
y = np.outer(np.cos(u), np.ones(len(h))) # y值重复20次
z = np.outer(np.ones(len(u)), h) # x,y 对应的高度

# Plot the surface
ax.plot_surface(x, y, z, cmap=plt.get_cmap('rainbow'))

plt.show()

圆锥面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
# 简单方法画出漂亮的圆锥体(底面在上,顶点在原点)
# 生成圆锥数据,底面半径为1,高度为1,其余的情形留待发挥
# 先根据极坐标方式生成数据
u = np.linspace(0, 2 * np.pi, 50) # linspace的功能用来创建等差数列
v = np.linspace(0, np.pi, 50)
# 数据转化为平面坐标数据
x = np.outer(np.cos(u), np.sin(v)) # outer(a,b) 外积:a的每个元素乘以b的每个元素,二维数组
y = np.outer(np.sin(u), np.sin(v))
z = np.sqrt(x ** 2 + y ** 2) # 圆锥体的高
# Plot the surface
ax.plot_surface(x, y, z, cmap=plt.get_cmap('rainbow'))
plt.show()

球面

1
2
3
4
5
6
7
8
9
10
11
12
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
u = np.linspace(0, 2 * np.pi, 50)
v = np.linspace(0, np.pi, 50)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, rstride=1, cstride=1,cmap=plt.get_cmap('rainbow'))
plt.show()

椭球面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
u = np.linspace(0, 2 * np.pi, 50)
v = np.linspace(0, np.pi, 50)
x = 5 * np.outer(np.cos(u), np.sin(v))
y = 4* np.outer(np.sin(u), np.sin(v))
z = 3 * np.outer(np.ones(np.size(u)), np.cos(v) )
ax.plot_surface(x, y, z, rstride=1, cstride=1,cmap=plt.get_cmap('rainbow'))
plt.xlim(-5,5)
plt.ylim(-5,5)
plt.xlabel("x")
plt.ylabel("y")
plt.savefig("10-12")
plt.show()

-------------本文结束,感谢您的阅读-------------