Python数据分析–matplotlib
官网:http://matplotlib.org/
学习方式:从官网examples入门学习
http://matplotlib.org/examples/index.html
http://matplotlib.org/gallery.html
什么是matplotlib
Matplotlib 是一个 Python 的 2D 绘图库, 通过 Matplotlib , 开发者可以仅需要几行代码, 便可 以生成折线图, 直方图, 条形图, 饼状图, 散点图等。
为什么要使用matplotlib
- 能将数据进行可视化,更直观的呈现
- 使数据更加客观、更具说服力
matplotlib三层结构
容器层
- 器层主要由Canvas、Figure、Axes组成。
- Canvas是位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布的工具
- Figure是Canvas上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。
- Axes是应用层的第二层,在绘图的过程中相当于画布上的绘图区的角色。
- Figure:指整个图形(可以通过plt.figure())设置画布的大小很分辨率等
- Axes(坐标系):数据的绘图区域。
- Axis(坐标轴):数坐标系中的一条轴,包含大小限制、刻度和刻度标签
图像层
图像层指Axes内通过plot、scatter、hist、bar、pie等函数根据数据绘制出的图像。
辅助层
辅助显示层为Axes内的除了根据数据绘制出的图像以外的内容,主要包括Axes外观(facecolor)、边框线(spines)、坐标轴(axis)、坐标轴名称(axis label)、坐标轴刻度(tick)、坐标轴刻度标签(tick label)、网格线(grid)、图例(legend)、标题(title)等内容。
matplotlib基本使用
# coding: utf-8
import matplotlib.pyplot as plt
#创建画布
fig = plt.figure()
#定义X轴数据
x = range(2, 26, 2)
#定义Y轴数据
y = [15, 13, 14, 5, 17, 10, 25, 26, 26, 24, 22, 18]
#创建折线图
plt.plot(x, y)
#展示
plt.show()
其中 plot 是一个画图的函数, 他的参数为 plot([x],y, [ fmt],data=None,**kwargs) 。 其 中 fmt 可以传一个字符串, 用来给这个图做一些样式修改的。 默认的绘制样式是 b- , 也就是蓝 色实体线条。
比如我想将原来的图的线条改成点状, 那么可以通过以下代码实现:
plt.plot(x, y, ':', color='r')
线条风格 | 描述 |
---|---|
‘-’ | 实线样式 |
‘–’ | 虚线样式 |
‘-.’ | 点划线样式 |
‘:’ | 虚线样式 |
线条标记 | 描述 |
---|---|
‘.’ | 点标记 |
‘,’ | 像素标记 |
‘o’ | 圆圈标记 |
‘v’ | 三角形向下标记 |
‘^’ | 三角形向上标记 |
‘<’ | 三角形左标记 |
‘>’ | 三角形_右标记 |
‘1’ | tri_down 标记 |
‘2’ | tri_up 标记 |
‘3’ | 三左标记 |
‘4’ | 三右标记 |
‘8’ | 八角形标记 |
‘s’ | 方形标记 |
‘p’ | 五边形标记 |
‘P’ | 加(填充)标记 |
‘*’ | 星标 |
‘h’ | 六边形1标记 |
‘H’ | 六边形2标记 |
‘+’ | 加号标记 |
‘x’ | x 标记 |
‘X’ | x(填充)标记 |
‘D’ | 钻石记号笔 |
‘d’ | Thin_diamond 标记 |
’ | ’ |
‘_’ | 线标记 |
颜色别名 | 描述 |
---|---|
‘b’ | blue |
‘g’ | green |
‘r’ | red |
‘c’ | cyan |
‘m’ | magenta |
‘y’ | yellow |
‘k’ | black |
‘w’ | white |
给线条设置颜色总体来说有三种方式:
- 使用颜色名称( r 是 red 的缩写)的形式
- 使用十六进制的方式
- 是使用 RGB 或 RGBA 的方式。
如果使用的是颜色名称,那么可以和线的形状写在同一个字符串中。比如使用红色的五角点,那么可以使用如下的方式实现:
plt.plot(x, y, 'rp') #r(红色) p(五角点)
样式设置DEMO
# coding: utf-8
import matplotlib.pyplot as plt
#figsize设置画布大小 dpi设置分辨率
fig = plt.figure(figsize=(6, 4), dpi=80)
x = range(2, 26, 2)
y1 = [15, 12, 14, 16, 17, 20, 25, 28, 21, 19, 18, 10]
y2 = [12, 14, 13, 18,12, 28, 23, 10, 19, 27, 20, 10]
# 创建多条折线图
# b(蓝色) label 标签
plt.plot(x, y1, 'b', label='y1')
#g(绿色)
plt.plot(x, y2, 'g', label='y2')
# X Y轴信息设置
plt.xlabel(u"时间")
plt.ylabel(u"温度 单位(℃)")
#修改X Y轴刻度
plt.xticks(range(2, 25))
plt.yticks(range(min(y1), max(y1)+1))
#设置网格 alpha表示透明度
plt.grid(linestyle=":", alpha=0.8),
#添加图例 loc图例显示位置
plt.legend(loc="best")
plt.show()
中文显示问题
中文字体下载地址 https://github.com/chenqing/ng-mini/raw/master/font/msyh.ttf
方法一
#-- coding: utf-8 --
......
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"./msyh.ttf", size=14)
plt.xlabel(u'职位需求(位)')
......
方法二
找到字体文件夹
import matplotlib
#查看matplotlib路径
print(matplotlib.matplotlib_fname())
将中文包放置 lib/site-packages/matplotlib/mpl-data/fonts/ttf/
修改 lib/site-packages/matplotlib/mpl-data/matplotlibrc文件
axes.unicode_minus : False ## use unicode for the minus symbol
font.family : Microsoft YaHei
font.sans-serif : Microsoft YaHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
第一行,修改True为False,是为了正常显示负号
第二行和第三行是为了使用微软雅黑作为默认字体
一个窗口,多个图,多条数据
# coding: utf-8
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(-5,5,0.1)
y=x*3
sub1=plt.subplot(211,facecolor=(0.1843,0.3098,0.3098)) #将窗口分成2行1列,在第1个作图,并设置背景色
sub2=plt.subplot(212) #将窗口分成2行1列,在第2个作图
sub1.plot(x,y) #绘制子图
sub2.plot(x,y) #绘制子图
axes1 = plt.axes([.2, .3, .1, .1], facecolor='y') #添加一个子坐标系,rect=[左, 下, 宽, 高]
plt.plot(x,y) #绘制子坐标系,
axes2 = plt.axes([0.7, .2, .1, .1], facecolor='y') #添加一个子坐标系,rect=[左, 下, 宽, 高]
plt.plot(x,y)
plt.show()
柱形图
# coding: utf-8
import matplotlib.pyplot as plt
import numpy as np
plt.figure(3)
x_index = np.arange(5) #柱的索引
x_data = ('A', 'B', 'C', 'D', 'E')
y1_data = (20, 35, 30, 35, 27)
y2_data = (25, 32, 34, 20, 25)
bar_width = 0.35 #定义一个数字代表每个独立柱的宽度
rects1 = plt.bar(x_index, y1_data, width=bar_width,alpha=0.4, color='b',label='legend1') #参数:左偏移、高度、柱宽、透明度、颜色、图例
rects2 = plt.bar(x_index + bar_width, y2_data, width=bar_width,alpha=0.5,color='r',label='legend2') #参数:左偏移、高度、柱宽、透明度、颜色、图例
#关于左偏移,不用关心每根柱的中心不中心,因为只要把刻度线设置在柱的中间就可以了
plt.xticks(x_index + bar_width/2, x_data) #x轴刻度线
plt.legend() #显示图例
plt.tight_layout() #自动控制图像外部边缘,此方法不能够很好的控制图像间的间隔
plt.show()
直方图
# coding: utf-8
import matplotlib.pyplot as plt
import numpy as np
fig,(ax0,ax1) = plt.subplots(nrows=2,figsize=(9,6)) #在窗口上添加2个子图
sigma = 1 #标准差
mean = 0 #均值
x=mean+sigma*np.random.randn(10000) #正态分布随机数
ax0.hist(x,bins=40,normed=False,histtype='bar',facecolor='yellowgreen',alpha=0.75) #normed是否归一化,histtype直方图类型,facecolor颜色,alpha透明度
ax1.hist(x,bins=20,normed=1,histtype='bar',facecolor='pink',alpha=0.75,cumulative=True,rwidth=0.8) #bins柱子的个数,cumulative是否计算累加分布,rwidth柱子宽度
plt.show() #所有窗口运行
散点图
# coding: utf-8
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(4) #添加一个窗口
ax =fig.add_subplot(1,1,1) #在窗口上添加一个子图
x=np.random.random(100) #产生随机数组
y=np.random.random(100) #产生随机数组
ax.scatter(x,y,s=x*1000,c='y',marker=(5,1),alpha=0.5,lw=2,facecolors='none') #x横坐标,y纵坐标,s图像大小,c颜色,marker图片,lw图像边框宽度
plt.show() #所有窗口运行
3D图
# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
fig = plt.figure()
ax = Axes3D(fig)
fig.add_axes(ax)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1)
plt.show()
动图
# coding: utf-8
from numpy import sin, cos
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
import matplotlib.animation as animation
from collections import deque
G = 9.8 # acceleration due to gravity, in m/s^2
L1 = 1.0 # length of pendulum 1 in m
L2 = 1.0 # length of pendulum 2 in m
L = L1 + L2 # maximal length of the combined pendulum
M1 = 1.0 # mass of pendulum 1 in kg
M2 = 1.0 # mass of pendulum 2 in kg
t_stop = 5 # how many seconds to simulate
history_len = 500 # how many trajectory points to display
def derivs(state, t):
dydx = np.zeros_like(state)
dydx[0] = state[1]
delta = state[2] - state[0]
den1 = (M1+M2) * L1 - M2 * L1 * cos(delta) * cos(delta)
dydx[1] = ((M2 * L1 * state[1] * state[1] * sin(delta) * cos(delta)
+ M2 * G * sin(state[2]) * cos(delta)
+ M2 * L2 * state[3] * state[3] * sin(delta)
- (M1+M2) * G * sin(state[0]))
/ den1)
dydx[2] = state[3]
den2 = (L2/L1) * den1
dydx[3] = ((- M2 * L2 * state[3] * state[3] * sin(delta) * cos(delta)
+ (M1+M2) * G * sin(state[0]) * cos(delta)
- (M1+M2) * L1 * state[1] * state[1] * sin(delta)
- (M1+M2) * G * sin(state[2]))
/ den2)
return dydx
# create a time array from 0..t_stop sampled at 0.02 second steps
dt = 0.02
t = np.arange(0, t_stop, dt)
# th1 and th2 are the initial angles (degrees)
# w10 and w20 are the initial angular velocities (degrees per second)
th1 = 120.0
w1 = 0.0
th2 = -10.0
w2 = 0.0
# initial state
state = np.radians([th1, w1, th2, w2])
# integrate your ODE using scipy.integrate.
y = integrate.odeint(derivs, state, t)
x1 = L1*sin(y[:, 0])
y1 = -L1*cos(y[:, 0])
x2 = L2*sin(y[:, 2]) + x1
y2 = -L2*cos(y[:, 2]) + y1
fig = plt.figure(figsize=(5, 4))
ax = plt.axes()
ax.set_xlim(-L, L)
ax.set_ylim(-L, 1)
# ax = ax.add_subplot(autoscale_on=False, xlim=(-L, L), ylim=(-L, 1.))
ax.set_aspect('equal')
ax.grid()
line, = ax.plot([], [], 'o-', lw=2)
trace, = ax.plot([], [], ',-', lw=1)
time_template = 'time = %.1fs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
history_x, history_y = deque(maxlen=history_len), deque(maxlen=history_len)
def animate(i):
thisx = [0, x1[i], x2[i]]
thisy = [0, y1[i], y2[i]]
if i == 0:
history_x.clear()
history_y.clear()
history_x.appendleft(thisx[2])
history_y.appendleft(thisy[2])
line.set_data(thisx, thisy)
trace.set_data(history_x, history_y)
time_text.set_text(time_template % (i*dt))
return line, trace, time_text
ani = animation.FuncAnimation(
fig, animate, len(y), interval=dt*1000, blit=True)
plt.show()