简介
matplotlib库 支持超过100种数据可视化的显示效果,每种显示效果 用户可以做自定义的修改。
matplotlib
和matplotlib.pyplot
的关系:
Matplotlib库 由各种可视化类构成,内部结构复杂, 受Matlab启发。而 Matplotlib.pyplot 是绘制各类可视化图形的 命令子库, 相当于快捷方式。
- 资源地址:
1)官网首页
2)matplotlib gallery 地址1
3)matplotlib gallery 地址2(图表更全一点)
4)matplotlib APIs 一般我们主要关注下面的matplotlib.axes
和matplotlib.pyplot
的API
- 知识点概览
全局设置
pyplot并不默认支持中文显示,需要 rcParams 修改字体 实现
- 改变全局字体
import matplotlib as mpl
mpl.rcParams['font.family'] = 'SimHei'
mpl.rcParams['axes.unicode_minus'] = False
rcParams
的属性
属性 | 说明 |
---|---|
‘font.family’ | 用于显示字体的名字 |
‘font.style’ | 字体风格,正常’normal’ 或 斜体’italic’ |
‘font.size’ | 字体大小,整数字号或者’large’, ‘x-small’ |
rcParams['font.family']
的属性(对应的中文字体种类)
中文字体 | 说明 |
---|---|
SimHei | 中文黑体 |
Kaiti | 中文楷体 |
Lisu | 中文隶书 |
FangSong | 中文仿宋 |
YouYuan | 中文幼圆 |
STSong | 华文宋体 |
二、常见配置
绘图风格
- 绘图风格
plt.style.use('seaborn-whitegrid')
plt.style.context('classic')
- 查看样式
plt.style.available[:5]
# ['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background']
- 临时使用某种风格绘图
with plt.style.context('seaborn-white'):
plt.plot(x, y)
常见的单图类型
图表名称 | 说明 |
---|---|
折线图plot() | 一个变量随时间变化的趋势关系 |
条形图bar()、水平条形图barh() | 分类变量或者离散变量的数量的多少 |
散点图scatter() | 因变量随自变量而变化的大致趋势 |
饼图pie() | 分类变量的占比分布 |
箱线图boxplot() | 一组数据分散情况 |
直方图hist() | 一个连续变量(定量变量)的概率分布的估计 |
- 均可以通过help()命令,查看API,用到什么查什么。
各类设置(标题、坐标轴等)
图表设置项 | 说明 |
---|---|
plt.title() | 标题 |
plt.xlabel() plt.ylabel() | x轴、y轴的标题 |
plt.xticks() plt.yticks() | x轴、y轴刻度 |
plt.tick_params() | 对x轴、y轴刻度的属性进行整体设置(如字体大小、颜色等) |
plt.xlims() plt.ylims() | x轴、y轴范围 |
plt.xscale() | plt.xscale(‘log’) 将坐标轴设置为对数坐标轴 |
plt.axis() | 可以用plt.axis同时对x、y的范围进行设置(见下面的例子) |
plt.text() | 在任意位置增加文本标签 |
plt.annotate() | 在图形中增加带箭头的注解 |
plt.legend() | 添加图例 |
plt.table() | 添加数据表 |
plt.grid() | 网格显示 |
plt.colorbar() | |
plt.show() | 结果展示 |
- plt.xlabel设置
- 改变需要显示中文的部分的字体(推荐)
plt.xlabel("横轴:日期", fontproperties = 'SimHei', fontsize = 20)
plt.ylabel("纵轴:数值", fontproperties = 'SimHei', fontsize = 20)
``
### - 同时指定横纵坐标范围 plt.axis
```python
plt.plot([0,2,4,6,8], [3,1,4,5,2])
plt.ylabel('grade')
plt.axis([-1,10, 0, 6]) #对应x的坐标轴范围为-1~10,y坐标轴范围 为 0~6
plt.axis('tight') # ('equal') # 'equal'使横纵坐标比例相同,使饼图变成正圆形的
?plt.axis # 可以查看样式
- 对单个图表上的属性整体设置 plt.tick_param
plt.tick_params(axis='both', labelsize=18, colors='b') # 设置轴标签属性
- 例子:图中的各类文本显示
import matplotlib.pyplot as plt
import numpy as np
a = np.arange(0.0, 5.0, 0.02)
plt.plot(a, np.cos(2 * np.pi * a), 'r--')
plt.xlabel('横轴:时间', fontproperties = 'SimHei', fontsize = 15, color = 'green')
plt.ylabel('纵轴:振幅', fontproperties = 'SimHei', fontsize = 15)
plt.title('正弦波实例 $y = cos(2\pi*x)$', fontproperties = 'SimHei', fontsize = 25)
plt.text(2,1,r'$\mu = 100$', fontsize = 15)
plt.axis([-1, 6,-2, 2])
plt.grid(True)
# 使用plt.annotate 添加注解
plt.annotate(r'$\mu = 100$', xy = (2,1), xytext = (3,1.5), arrowprops = dict(facecolor = 'black', shrink = 0.1, width = 2))
plot里的参数(颜色、风格、标识)
plt.plot(x, y, format_string, ****kwargs**)
其中,kwargs 中 可以指定
color: 控制颜色,如 color = ‘green’
linestyle: 线条风格,如 linestyle = ‘dashed’
marker: 标记风格,如 marker = ‘o’
markerfacecolor: 标记颜色,如 markerfacecolor = ‘blue’
- 颜色字符
color
颜色字符 | 说明 |
---|---|
b | 蓝色 |
g | 绿色 |
r | 红色 |
y | 黄色 |
k | 黑色 |
w | 白色 |
c | 青绿色 cyan |
m | 洋红色 magenta |
#008000 | RGB某颜色 |
0.8 | 灰度值字符串 |
- 风格字符
linestype
及 标记字符marker
字符 | 类型 | 字符 | 类型 |
---|---|---|---|
'-' | 实线 solid | '--' | 虚线 dashed |
'-.' | 虚点线 dashdot | ':' | 点线 dotted |
'.' | 点 | ',' | 像素点 |
'o' | 圆点 | 'v' | 下三角点 |
'^' | 上三角点 | '<' | 左三角点 |
'>' | 右三角点 | '1' | 下三叉点 |
'2' | 上三叉点 | '3' | 左三叉点 |
'4' | 右三叉点 | 's' | 正方点 |
'p' | 五角点 | '*' | 星形点 |
'h' | 六边形点1 | 'H' | 六边形点2 |
'+' | 加号点 | 'x' | 乘号点 |
'D' | 实心菱形点 | 'd' | 瘦菱形点 |
'_' | 横线点 |
标记字符 | 说明 | 标记字符 | 说明 | 标记字符 | 说明 |
---|---|---|---|---|---|
’.’ | 点标记 | ‘1’ | 下花三角标记 | ‘h’ | 竖六边形标记 |
’,’ | 像素标记(极小点) | ‘2’ | 上花三角标记 | ‘H’ | 横六边形标记 |
’o’ | 实心圆标记 | ‘3’ | 左花三角标记 | ‘+’ | 十字标记 |
’v’ | 倒三角标记 | ‘4’ | 右花三角标记 | ‘x’ | x标记 |
’^’ | 上三角标记 | ‘s’ | 实心方形标记 | ‘D’ | 菱形标记 |
’>’ | 右三角标记 | ‘p’ | 实心五角标记 | ‘d’ | 瘦菱形标记 |
’<’ | 左三角标记 | ‘*’ | 星形标记 | ‘|’ | 竖直线标记 |
用户在使用的过程中,可以任意指定上述三种字符中的一种或几种
a = np.arange(110)
plt.plot(a, a*1.5, 'o-', a, a*2.5, 'rx', a, a*3.5, '*', a*4.5, 'b-.')
自动调整图像外部边缘(tight_layout)
fig.tight_layout()
颜色配置 cmaps
颜色示例参考这个链接
三、绘制多个子图
通过plt.subplots
在全局绘图区域中创建一个分区体系,并定位到一个子绘图区域。后面在subplot中绘制的图形 全部在这些子区域中进行绘制。
3.1 分开的多个子图
3.1.1 方法一:直接操作plt.subplot
import matplotlib.pyplot as plt
import numpy as np
def f(t):
return np.exp(-t) * np.cos(2 * np.pi * t)
a = np.arange(0.0, 5.0, 0.02)
plt.subplot(211); plt.plot(a, f(a))
plt.subplot(212); plt.plot(a, np.cos(2*np.pi*a), 'r--')
plt.show()
3.1.2 方法二(推荐):面向对象绘图
1)先生成fig,再通过fig.add_subplot()分步生成对象ax
fig = plt.figure(figsize(12, 6))
ax1 = fig.add_subplot(221)
ax1.plot(htime, hstrain, 'y')
# 对图像设置标签、标题等参数
ax1.set_xlabel('Time(Seconds)')
ax1.set_ylabel('H1 Strain')
ax1.set_title('H1 Strain')
2)生成fig和ax,调用ax对象的方法(推荐)
通过
plt.subplots
同时创建fig和ax,后面调用ax这一对象的方法。
- 单个ax对象
# 单个ax对象(未设置nrows和ncols两个参数)
fig, ax = plt.subplots(figsize=(9.2, 5))
ax.invert_yaxis()
ax.xaxis.set_visible(False)
ax.barh(labels, widths, left=starts, height=0.5,
label=colname, color=color)
ax.set_xlim(0, np.sum(data, axis=1).max())
ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),
loc='lower left', fontsize='small')
- 多个ax对象
可以直接通过axes[0], axes[1], … 来对每个axes对象调用方法
# 多个ax对象(设置了nrows和ncols两个参数)
import matplotlib.pyplot as plt
import numpy as np
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(9, 4))
# generate some random test data
all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]
# plot violin plot
axes[0].violinplot(all_data,
showmeans=False,
showmedians=True)
axes[0].set_title('violin plot')
# plot box plot
axes[1].boxplot(all_data)
axes[1].set_title('box plot')
# adding horizontal grid lines
for ax in axes:
ax.yaxis.grid(True)
ax.set_xticks([y+1 for y in range(len(all_data))])
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# add x-tick labels
plt.setp(axes, xticks=[y+1 for y in range(len(all_data))],
xticklabels=['x1', 'x2', 'x3', 'x4'])
plt.show()
3)生成fig和ax,通过DataFrame.plot()方法,在参数中指定ax
对DataFrame调用plot方法,在plot方法中指定ax=axes[0], ax=axes[1], … 等
(这种方法的好处是DataFrame的plot()方法里面的参数非常丰富,很多 如标题、图像大小、字体大小等可以直接在plot()的参数里面设置,比较方便。)
# 直接定义:
fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True, sharey=True, figsize=(12, 7))
# 在上面的基础上画图:
df1.plot(style = 'k-', ax = axes[0])
df2.plot(stype = 'k--', ax = axes[0])
df3.plot(stype = 'k-', ax = axes[1]
df4.plot(stype = 'k--', ax = axes[1]
# 分别定义 两个子图的标题:
axes[0].set_title('Title1')
axes[1].set_title('Title2')
3.1.4 通过DataFrame的plot方法绘图
df.plot? # 查看文档
# 多子图
df.plot(subplots=True, figsize=(15,5))
# 两行两列
df.plot(subplots=True, layout=(2,2), figsize=(15,5), sharex=False)
DataFrame自带的plot方法非常强大,很多参数简单传入plot()即可实现多样的图表展现功能,如secondary_y
、subplots
、layout
等。(具体可以参考这个文档)
3.1.3 不规则子图(子区域自定义)
有时候我们想要自定义子区域的长宽等,可以通过以下两种方法实现(效果等价)。
- 方法1:
matplotlib.pyplot.subplot2grid
plt.subplot2grid((3,3), (0,0), colspan = 3)
plt.subplot2grid((3,3), (1,0), colspan = 2)
plt.subplot2grid((3,3), (1,2), rowspan = 2)
- 方法2:
matplotlib.gridspec
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3,3, wspace=0.4, hspace=0.3)
ax1 = plt.subplot(gs[0, :])
ax1 = plt.subplot(gs[1, :-1])
ax1 = plt.subplot(gs[1:, -1:])
ax1 = plt.subplot(gs[2, 0])
ax1 = plt.subplot(gs[2, 1])
3.2 叠加在同一个图上的多个子图
sharex, sharey 参数
ax.twinx 方法
用pandas DataFrame的绘图参数中的 secondary_y
3.2.1 方法一:ax.twix()
x = list(gdp.year)
GDP = list(gdp.GDP)
GDPCR = list(gdp.GDPCR)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.bar(x,GDP)
ax1.set_ylabel('GDP'); ax1.set_title("GDP of China(2000-2017)")
ax1.set_xlim(2000,2017)
ax2 = ax1.twinx() # 指定twix
ax2.plot(x,GDPCR,'r')
ax2.set_ylabel('Increase Ratio'); ax2.set_xlabel('Year')
3.2.2 方法二:DataFrame.plot()指定secondary_y参数
通过在DataFrame的plot()的方法中,指定secondary_y=True
# 帕累托图
plt.figure()
# 先绘制盈利金额的柱图
data.plot(kind='bar')
plt.ylabel(u'盈利(元)')
# 再绘制累计百分比图,设置 secondary_y=True
p = 1.0 * data.cumsum() / data.sum()
p.plot(color='r', secondary_y=True, style='-o', linewidth=2)
plt.annotate(format(p[6], '.4%'), xy=(6, p[6]), xytext=(6 * 0.9, p[6] * 0.9), arrowprops=dict(
arrowstyle="->", connectionstyle="arc3,rad=.2")) # 添加注释,即85%处的标记。这里包括了指定箭头样式。
plt.ylabel(u'盈利(比例)')
plt.show()
3.3 画中画
x = np.linspace(0,5,10)
y = x**2
fig = plt.figure()
ax1 = fig.add_axes([0.1,0.1,0.8,0.8])
ax2 = fig.add_axes([0.2,0.5,0.4,0.3])
ax1.plot(x,y,'r'); ax1.set_xlabel('x', fontsize=15); ax1.set_ylabel('y', fontsize=15); ax1.set_title('title', fontsize=15)
ax2.plot(y,x,'g'); ax2.set_xlabel('y', fontsize=15); ax2.set_ylabel('x', fontsize=15); ax2.set_title('inner title', fontsize=15)
四、将输出文件保存图像
发布图片时最长用到的两个重要的选项是dpi(控制"每英寸点数"分辨率)和bbox_inches(可以剪除当前图表周围的空白部分)。
savefig并非一定要写入磁盘,也可以写入任何文件型的对象,比如StringIO, 这对在Web上提供动态生成的图片是很实用的。
- 保存并关闭图像
plt.savefig(path+filename, dpi = 600) #图片默认会保存为png格式,filename后缀不用加文件类型
plt.show(); plt.close(fig)
- Figure.savefig 方法的参数
参数 | 说明 |
---|---|
fname | 文件名。图像格式由文件扩展名推断得出。 |
dpi | 图像分辨率(每英寸点数),默认为100 |
facecolor, edgecolor | 图像的背景色,默认为’w’(白色) |
format | 显式设置文件格式(如 ‘png’, ‘pdf’, ‘svg’, ‘ps’, ‘eps’, …) |
bbox_inches | 图表需要保存的部分,如果设置为’right’,则将尝试剪除图表周围的空白部分 |
五、基础图表简单示例
- pyplot基础图表函数
# 坐标图
plt.plot(x, y, fmt,...)
# 箱线图
plt.boxplot(data, notch, position)
# 柱形图
plt.bar(left, height, width, bottom)
# 横向条形图
plt.barh(width, bottom, left, height)
# 极坐标图
plt.polar(theta, r)
# 饼图
plt.pie(data, explode)
# 散点图
plt.scatter(x, y)
# 步阶图
plt.step(x, y, where)
# 直方图
plt.hist(x, bins, normed)
# 绘制数据日期
plt.plot_data()
柱图
plt.bar(..., color='yellow', edgecolor='red')
# 替换坐标轴
plt.xticks(x, ['G1', 'G2', 'G3', 'G4', 'G5'])
- matplotlib
- 在plt.rcParams里配置显示中文(推荐)
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决图像保存时 负号'-'显示是方块的问题
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b =[38.13,19.85,14.89,11.36,6.47,5.93]
plt.figure(figsize=(20,8),dpi=80)
# 绘制条形图
rects = plt.bar(range(len(a)),b,width=0.9,color= 'red')
plt.xticks(range(len(a)),a, fontsize=15)
plt.yticks(range(0,41,5),range(0,41,5), fontsize=15)
plt.title('高分电影排名情况', fontsize=20)
# 在条形图上加标注(水平居中)
for rect in rects:
#获取高度,y值
height = rect.get_height()
#设置显示文字
plt.text(rect.get_x() + rect.get_width() / 2, height+0.3, str(height),ha="center", fontsize=15)
plt.show()
- 用font_manager指定中文类型
from matplotlib import pyplot as plt
from matplotlib import font_manager
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b =[38.13,19.85,14.89,11.36,6.47,5.93]
my_font = font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=10)
plt.figure(figsize=(20,8),dpi=80)
# 绘制条形图
rects = plt.bar(range(len(a)),b,width=0.9,color= 'red')
plt.xticks(range(len(a)),a,fontproperties=my_font, fontsize=15)
plt.yticks(range(0,41,5),range(0,41,5), fontsize=15)
plt.title('高分电影排名情况', fontproperties=my_font, fontsize=20)
# 在条形图上加标注(水平居中)
for rect in rects:
#获取高度,y值
height = rect.get_height()
#设置显示文字
plt.text(rect.get_x() + rect.get_width() / 2, height+0.3, str(height),ha="center", fontsize=15)
plt.show()
- 横向条形图
x = ['G'+str(i) for i in range(1,6)]
y = 2*np.arange(1,6)
plt.figure(figsize=(10,5))
plt.barh(x,y, align='center',height=0.5,alpha=0.8,color='b', edgecolor='r')
plt.tick_params(axis='both', labelsize=18, colors='b') # 设置轴标签属性
- 用matplotlib绘制堆叠柱图
import matplotlib.pyplot as plt
import numpy as np
index = np.arange(4)
BJ = np.random.randint(20,30,4)
Sh = np.random.randint(20,30,4)
plt.rcParams['font.size'] = 15
plt.figure(figsize=(10,5))
# 堆叠柱形
plt.bar(index,BJ,width=0.3,label='BJ')
plt.bar(index,Sh,bottom=BJ,width=0.3,color='lightgrey', label='SH')
plt.xticks(index,['group'+str(i) for i in index])
plt.legend()
- 用matplotlib绘制簇状柱图
import matplotlib.pyplot as plt
import numpy as np
index = np.arange(4)
BJ = [50,55,53,60]
Sh = [44,66,55,41]
plt.rcParams['font.size'] = 15
plt.figure(figsize=(10,5))
#并列柱形
plt.bar(index,BJ,width=0.3, label='BJ')
plt.bar(index+0.3,Sh,width=0.3,color='lightgrey', label='SH')
plt.xticks(index+0.15,index)
plt.legend()
- Series和DataFrame的plot()方法
- Series也有plot方法,可以直接调用(在plot方法的参数里面配置图表类型)
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决图像保存时 负号'-'显示是方块的问题
plt.rcParams['font.size'] = 15 # matplotlib 默认字体大小
plt.rcParams['figure.figsize'] = (15, 10) # matplotlib 默认图像大小
fig, axes = plt.subplots(2,1)
data = Series(np.random.rand(16), index=list('abcdefghijklmnop'))
data.plot(kind='bar', ax=axes[0], color='k', alpha=0.7)
data.plot(kind='barh', ax=axes[1], color='g', alpha=0.7)
- 用plot方法直接绘制多列的DataFrame
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
df = DataFrame(np.random.rand(6,4),columns=['A', 'B', 'C', 'D'])
df.plot(kind='bar', figsize=(15,5), title='用plot方法直接绘制多列的DataFrame')
- 加上
subplots=True
,每列绘制到单独的子图中
df = DataFrame(np.random.rand(6,4),columns=['A', 'B', 'C', 'D'])
df.plot(kind='bar', subplots=True, title='DataFrame的plot方法-绘制多个子图') # 加上 subplots=True,每列绘制到单独的子图中
- 加上
stacked=True
,绘制堆叠柱图
df = DataFrame(np.random.rand(6,4),columns=['A', 'B', 'C', 'D'])
df.plot(kind='barh', stacked=True, alpha=0.5, title='DataFrame的plot方法-绘制堆叠柱图', figsize=(15,5))
折线图
- 用matplotlib来画(plt.plot() )
def f(t):
return np.exp(-t)*np.cos(2*np.pi*t)
t1 = np.arange(0,5,0.1)
t2 = np.arange(0,5,0.02)
plt.figure(figsize=(15,8))
plt.subplot(211)
plt.plot(t1, f(t1), 'bo-', markerfacecolor='r', markersize=5)
plt.ylabel('Damped oscillation')
plt.title('A tale of 2 subplots')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.xlabel('time(s)')
plt.ylabel('Undamped')
饼图
-
饼图参数
explode:设置各部分突出
label:设置各部分标签
labeldistance:设置标签文本距圆心位置,1.1表示1.1倍半径
autopct:设置圆里面文本
shadow:设置是否有阴影
startangle:起始角度,默认从0开始逆时针转
pctdistance:设置圆内文本距圆心距离 -
简单饼图
labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0)
plt.pie(sizes, explode = explode, labels = labels, autopct = '%1.1f%%', shadow = False, startangle = 90)
plt.axis('equal') # 使横纵坐标比例相同,使饼图变成正圆形的
- 饼图指定颜色
import matplotlib.pyplot as plt
import matplotlib
label_list = ["第一部分", "第二部分", "第三部分"] # 各部分标签
size = [55, 35, 10] # 各部分大小
color = ["pink", "lightgrey", "lightblue"] # 各部分颜色
explode = [0, 0.05, 0] # 各部分突出值
plt.figure(figsize=(5, 5), dpi=100)
plt.pie(
size,
explode=explode,
colors=color,
labels=label_list,
labeldistance=1.1,
autopct="%1.1f%%",
shadow=False,
startangle=90,
pctdistance=0.6,
)
直接绘制的饼图上方会有三个返回值:
- 返回值:
patches : matplotlib.patches.Wedge列表(扇形实例)
l_text:label matplotlib.text.Text列表(标签实例)
p_text:label matplotlib.text.Text列表(百分比标签实例)
可以通过接收三个返回值
来避免其打印出来,不美观。
plt.figure(figsize=(5, 5), dpi=100)
patches, l_text, p_text = plt.pie(
size,
explode=explode,
colors=color,
labels=label_list,
labeldistance=1.1,
autopct="%1.1f%%",
shadow=False,
startangle=90,
pctdistance=0.6,
)
plt.legend()
直方图
np.random.seed(0)
mu, sigma = 100, 20 # 均值 和 标准差
a = np.random.normal(mu, sigma, size = 100)
plt.figure(figsize=(10,5))
plt.hist(a, 20, density=True, histtype='stepfilled', facecolor='b', alpha=0.75)
#bins = 20, 表示直方的个数
#density=True: 纵坐标是出现的概率;density=False: 纵坐标是出现的个数
plt.title('Histogram', fontsize=18)
- 画一个标准直方图
from scipy.stats import norm
mu, sigma = 100,15
x = mu + sigma*np.random.randn(10000)
plt.figure(figsize=(10,5))
_, bins, __ = plt.hist(x, 50, density=True)
# 绘制一条拟合的正态分布的线,用于对比
y = norm.pdf(bins, mu, sigma)
plt.plot(bins, y, 'r--', lw=3)
plt.xlabel('Smarts', fontsize=15); plt.ylabel('Probability', fontsize=15)
plt.tick_params(axis='both', labelsize=13) # 设置轴标签属性
plt.title('Histogram of IQ', fontsize=18)
plt.text(60, 0.025, r'$\mu=100,\ \sigma=15$')
plt.axis([40,160,0,0.03])
- 例子:电影时长分布
time = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114,
119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99,
136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144,
105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123,
117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116,
108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125,
138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,
107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109,
106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123,
111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109,
141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103,
130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98,
117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111,
101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116,
111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]
distance = 2 # 设置组距
group_num = int((max(time) - min(time)) / distance) # 计算组数
plt.figure(figsize=(15, 5), dpi=100)
plt.hist(time, bins=group_num) # 绘制直方图
plt.xticks(range(min(time), max(time))[::2]) # 修改x轴刻度显示
plt.grid(linestyle="--", alpha=0.5) # 添加网格显示
plt.xlabel("电影时长大小")
plt.ylabel("电影的数据量")
plt.title('电影时长分布直方图', fontsize=20)
- 累计直方图(累计概率分布)
mu, sigma = 100,15
x = mu + sigma*np.random.randn(10000)
plt.figure(figsize=(10,5))
_, bins, __ = plt.hist(x, 50, density=True, cumulative=True)
plt.xlabel('Smarts', fontsize=15); plt.ylabel('Cum_Probability', fontsize=15)
plt.tick_params(axis='both', labelsize=13) # 设置轴标签属性
plt.title('Histogram of IQ', fontsize=18)
plt.text(60, 0.8, r'$\mu=100,\ \sigma=15$', fontsize=15)
plt.axis([40,160,0,1.1])
plt.grid()
- 分组直方图
# 用上面的电影市场数据构造一个分组数据
df = DataFrame(time, columns=['number'])
df['groups']=index=list('abcde')*50
df.hist(column='number', by=['groups'],
sharex=True, sharey=True,
layout=(5, 1),
grid=False, xlabelsize=10,
figsize=(10, 10))
散点图
#使用面向对象的方法绘制散点图
fig, ax = plt.subplots() #fig, ax 分别对应图表 和 图表绘制的区域
ax.plot(10 * np.random.randn(100), 10 * np.random.randn(100), 'o')
# randn 生成正态分布的点
ax.set_title('Simple Scatter')
六边形图
df = pd.DataFrame(np.random.randn(1000,2), columns=['a', 'b'])
df['b'] = df['b']+np.arange(1000)
df['z'] = np.random.uniform(0,3,1000)
df.plot.hexbin(x='a', y='b', C='z',
reduce_C_function=np.max,
gridsize=25,
figsize=(10,7))
用来绘制六边形图的数据看上去不好理解。我们下面看一下这三个变量各自的分布情况。
可以看到,a符合正态分布,b更接近于均匀分布。六边形图是以a作为x轴,b作为y轴,ab区域内的 max(z)
(根据reduce_C_function
参数指定)是六边形的颜色深度。所以,六边形图在x方向上呈现出中间密集、两边稀疏的现象;在y轴上则基本上比较均匀。
误差图
- 基本误差图
x = np.linspace(0,10,50)
dy = 0.5
y = np.sin(x)+dy*np.random.randn(50)
plt.figure(figsize=(10,5))
plt.errorbar(x,y, yerr=dy, fmt='+b')
- 柱形误差图
menMeans = (20,35,30,35,27)
womenMeans = (25,32,34,20,25)
menStd = (2,3,4,1,2)
womenStd = (3,5,2,3,3)
ind = ['G'+str(i) for i in range(1,6)]
width = 0.35
p1 = plt.bar(ind, menMeans, width=width,label='Men', yerr=menStd)
p2 = plt.bar(ind, womenMeans, width=width, bottom=menMeans, label='Women', yerr=womenStd)
plt.ylabel('Score', fontsize=15)
plt.title('Score by group and gender', fontsize=18)
plt.yticks(np.arange(0,81,10), fontsize=13)
plt.legend()
三维图
- 三维数据点与线
from mpl_toolkits import mplot3d
ax = plt.axes(projection='3d')
zline = np.linspace(0,15,1000)
xline = np.sin(zline)
yline = np.cos(zline)
ax.plot3D(xline, yline, zline)
zdata = 15*np.random.random(100)
xdata = np.sin(zdata)
ydata = np.cos(zdata)
ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='spring')
- 三维数据曲面图
def f(x,y):
return np.sin(np.sqrt(x**2+y**2))
x = np.linspace(-6,6,30)
y = np.linspace(-6,6,30)
X, Y = np.meshgrid(x,y)
Z = f(X, Y)
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis')
六、附
一些美化配置
- 图像大小及dpi
plt.figure(figsize=(20,8),dpi=80)
- 坐标轴设置(刻度、标签)
# 设置x轴的刻度
plt.xticks(x)
plt.xticks(range(1,25))
# 设置y轴的刻度
plt.yticks(y)
plt.yticks(range(min(y),max(y)+1))
# 构造x轴刻度标签
x_ticks_label = ["{}:00".format(i) for i in x]
#rotation = 45 让字旋转45度
plt.xticks(x,x_ticks_label,rotation = 45)
# 设置y轴的刻度标签
y_ticks_label = ["{}℃".format(i) for i in range(min(y),max(y)+1)]
plt.yticks(range(min(y),max(y)+1),y_ticks_label)
pyplot.subplots参数
参数 | 说明 |
---|---|
nrows | subplot的行数 |
ncols | subplotd的列数 |
sharex | 所有subploty使用相同的x轴刻度(调节xlim会影响所有的subplot) |
sharey | 所有subploty使用相同的y轴刻度(调节ylim会影响所有的subplot) |
subplot_kw | 用于创建各subplot的关键字字典 |
**fig_kw | 创建figure时的其他关键字,如 plt.subplots(2,2, figsize=(8,6)) |
- 调整subplot周围的间距
利用Figure的subplots_adjust
方法可以轻而易举地修改间距. 此外,它也是个顶级函数:
subplot_adjust(left=None, bottom = None, right = None, top=None, wspace = None, hspace = None)
#wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距
#例如:
plt.subplot_adjusts(hspace=0.5, wspace=0.3)
plt.subplots(321)
plt.scatter(x,y,s=80, c='b', marker='>')
plt.subplots(322)
plt.scatter(x,y,s=80, c='g', marker='*')
...
DataFrame.plot()参数
DataFrame还有一些用于对列进行灵活处理的选项. 例如,是要将所有列都绘制到一个subplot中还是创建各自的subplot。
参数 | 说明 |
---|---|
subplots | 将各个DataFrame列绘制到单独的subplot中 |
sharex | 如果subplots=True,则共用一个X轴,包括刻度和界限 |
sharey | 如果subplots=True,则共用一个Y轴,包括刻度和界限 |
figsize | 表示图像大小的元组 |
title | 表示图像标题的字符串 |
legend | 添加一个subplot的图例(默认为True) |
sort_columns | 以字母表顺序绘制各列,默认使用当前列顺序 |
-
生成线型图的代码中加上
kind='bar'
(垂直柱状图)或kind='barh'
(水平柱状图)即可生成柱状图。 -
设置
stacked=True
,可为DataFrame生成堆积柱状图,这样每行的值就会被堆积在一起。
Series.plot()参数
参数 | 说明 |
---|---|
label | 用于图例的标签 |
ax | 要在其上进行绘制的ax对象。如果没有指定,则使用当前的subplot |
style | 要传给matplotlib的风格字符串(如’ko–’) |
alpha | 图表的填充不透明度(0~1) |
kind | 图表类型,如 ‘line’, ‘bar’, ‘barh’, ‘kde’ |
logy | 在y轴上使用对数标尺 |
use_index | 将对象的索引用作刻度标签 |
rot | 旋转刻度标签(0~360) |
xticks | 用作x轴刻度的值 |
yticks | 用作y轴刻度的值 |
xlim | x轴的界限(如 [0,10]) |
ylm | y轴的界限 |
grid | 显示轴网格线(默认打开) |