目录
使用pylab或pyplot绘图的一般过程为:
(1)首先生成或读入数据
(2)然后根据实际需要绘制折线图、散点图、柱状图、饼状图、雷达图或三维曲线和曲面
(3)接下来设置坐标轴标签、坐标轴刻度、图例、标题、保存或显示
每一种图形都有特定的应用场景,对于不同类型的数据和可视化要求,要选择最适合类型的图形进行展示,不要生硬地套用某种图形。
基本绘图流程如下:

第一部分主要作用是构建出一张空白的画布,并可以选择是否将整个画布划分为多个部分,方便在同一幅图上绘制多个图形的情况。最简单的绘图可以省略第一部分,而后直接在默认画布上进行图形绘制。
| 函数名称 | 函数作用 |
| plt.figure | 创建一个空白画布,可以指定画布大小、像素 |
| figure.add_subplot | 创建并选中子图,可以指定子图的行数、列数,与选中图片编号 |
第二部分是绘画的主体部分。其中添加标题,坐标轴名称,绘制图形等步骤是并列的,没有先后顺序,可以先绘制图形,也可以先添加各种标签。但是添加图例一定要在绘制图形之后。

第三部分主要用于保存和显示图形。

pyplot使用rc配置文件来自定义图形的各种默认属性,被称为rc配置或rc参数。
在pyplot中几乎所有的默认属性都是可以控制的,例如视图窗口的大小以及每英寸点数、线条宽度、颜色和样式、坐标轴、坐标和网络属性、文本、字体等。
线条的常用rc参数名称、解释与取值。

常用线条类型解释。

线条标记解释。

【注意事项】
(1)由于默认的pyplot字体并不支持中文字符的显示,因此需要通过设置font.sans-serif参数改变绘图时的字体,使得图形可以正常显示中文。同时,由于更改字体后,会导致坐标轴中的部分字符无法显示,因此需要同时更改axes.unicode_minus参数。

(2)除了设置线条和字体的rc参数外,还有设置文本、箱线图、坐标轴、刻度、图例、标记、图片、图像保存等rc参数。具体参数与取值可以参考官方文档。
折线图(line chart)是一种将数据点按照顺序连接起来的图形。可以看作是将散点图,按照x轴坐标顺序连接起来的图形。
折线图的主要功能是查看因变量y随着自变量x改变的趋势,最适合用于显示随时间(根据常用比例设置)而改变的连续数据。同时还可以看出数量的差异,增长趋势的变化。
matplotlib.pyplotplot(*args,**kwargs)
plot函数在官方文档的语法中只要求填入不定长参数,实际可以填入的主要参数如下:

color参数的8种常用颜色的缩写:

- >>> import numpy as np
- >>> import pylab
- >>> import pylab as pl
- >>> import matplotlib.font_manager as fm
- >>> myfont=fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf')
- >>> t=np.arange(0.0,2.0*np.pi,0.01)
- >>> s=np.sin(t)
- >>> z=np.cos(t)
- >>> pl.plot(t,s,label='正弦')
- [
object at 0x00000224D75A7F70>] - >>> pl.plot(t,z,label='余弦')
- [
object at 0x00000224D75F02B0>] - >>> pl.xlabel('x-变量',fontproperties='STKAITI',fontsize=18)
- Text(0.5, 0, 'x-变量')
- >>> pl.ylabel('y-正弦余弦函数值',fontproperties='simhei',fontsize=18)
- Text(0, 0.5, 'y-正弦余弦函数值')
- >>> pl.title('sin-cos函数图像',fontproperties='STLITI',fontsize=24)
- Text(0.5, 1.0, 'sin-cos函数图像')
- >>> pl.legend(prop=myfont)
object at 0x00000224D75A5D20> - >>> pl.show()

某质点初始速度和加速度已知,绘制该质点第5秒到20秒之间速度和位移的曲线。
- import numpy as np
- import matplotlib.pyplot as plt
-
- #初始速度
- v0=3
- #加速度
- a=1.8
- #时间轴,第5到20秒
- t=np.arange(5,21)
- #速度
- v=v0+a*t
- #位移
- x=v0*t+0.5*a*t*t
-
- #创建左右两个子图
- fig=plt.figure()
- ax1=plt.subplot(121)
- ax2=plt.subplot(122)
-
- #在左边子图中绘制速度曲线
- plt.sca(ax1)
- plt.plot(t,v,c='red')
- plt.title('时间-速度',fontproperties='STKAITI',fontsize=24)
- plt.xlabel('时间(s)',fontproperties='STKAITI',fontsize=18)
- plt.ylabel('速度(m/s)',fontproperties='STKAITI',fontsize=18)
-
- #设置坐标轴跨度
- plt.xlim(5,21)
- plt.ylim(0,40)
-
- #在右边子图中绘制位移曲线
- plt.sca(ax2)
- plt.plot(t,x,c='blue')
- plt.title('时间-唯一',fontproperties='STKAITI',fontsize=24)
- plt.title('时间-位移',fontproperties='STKAITI',fontsize=24)
- plt.xlabel('时间(s)',fontproperties='STKAITI',fontsize=18)
- plt.ylabel('位移(m)',fontproperties='STKAITI',fontsize=18)
- plt.xlim(5,21)
- plt.ylim(0,450)
-
- #设置子图之间的水平间距,wspace单位为子图宽度的比例
- plt.subplots_adjust(wspace=0.5)
- plt.show()

- import numpy as np
- import matplotlib.pyplot as plt
-
- x=np.linspace(0,2*np.pi,500)
- y1=np.sin(x)
- y2=np.cos(x)
- y3=np.sin(x*x)
- plt.figure(1)
- ax1=plt.subplot(2,2,1)
- ax2=plt.subplot(2,2,2)
- ax3=plt.subplot(212,facecolor='y')
- plt.sca(ax1)
- plt.plot(x,y1,color='red')
- plt.ylim(-1.2,1.2)
- plt.sca(ax2)
- plt.plot(x,y2,'b--')
- plt.ylim(-1.2,1.2)
- plt.sca(ax3)
- plt.plot(x,y3,'g--')
- plt.ylim(-1.2,1.2)
- plt.show()


- import matplotlib.pyplot as plt
- import matplotlib.font_manager as fm
-
- # 进价
- basePrice = 49
- #零售价
- salePrice = 75
-
- # 计算购买num个商品时的单价,买的越多,单价越低
- def compute(num):
- return salePrice * (1-0.01*num)
-
- # numbers用来存储顾客购买数量
- # earns用来存储商场的盈利情况
- # totalConsumption用来存储顾客消费总金额
- # saves用来存储顾客节省的总金额
- numbers = list(range(1, 31))
- earns = []
- totalConsumption = []
- saves = []
-
- # 根据顾客购买数量计算三组数据
- for num in numbers:
- perPrice = compute(num)
- earns.append(round(num*(perPrice-basePrice), 2))
- totalConsumption.append(round(num*perPrice, 2))
- saves.append(round(num*(salePrice-perPrice), 2))
-
- # 绘制商家盈利和顾客节省的折线图,系统自动分配线条颜色
- plt.plot(numbers, earns, label='商家盈利')
- plt.plot(numbers, totalConsumption, label='顾客总消费')
- plt.plot(numbers, saves, label='顾客节省')
-
- # 设置坐标轴标签文本
- plt.xlabel('顾客购买数量(件)', fontproperties='simhei')
- plt.ylabel('金额(元)', fontproperties='simhei')
-
- # 设置图形标题
- plt.title('数量-金额关系图', fontproperties='stkaiti', fontsize=20)
-
- # 创建字体,设置图例
- myfont = fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf',
- size=12)
- #显示图例
- plt.legend(prop=myfont)
-
- # 计算并标记商家盈利最多的批发数量
- maxEarn = max(earns)
- bestNumber = numbers[earns.index(maxEarn)]
-
- # 散点图,在相应位置绘制一个红色五角星,详见3.3节
- plt.scatter([bestNumber], [maxEarn], marker='*', color='red', s=120)
-
- # 使用annotate()函数在指定位置进行文本标注
- plt.annotate(xy=(bestNumber, maxEarn), # 箭头终点坐标
- xytext=(bestNumber-1, maxEarn+200),# 箭头起点坐标
- s=str(maxEarn), # 显示的标注文本
- arrowprops=dict(arrowstyle="->")) # 箭头样式
-
- plt.savefig('a.jpg')
- # 显示图形
- plt.show()


- import matplotlib.pyplot as plt
-
- #月份和每月营业额
- month = list(range(1,13))
- money = [5.2, 2.7, 5.8, 5.7, 7.3, 9.2,
- 18.7, 15.6, 20.5, 18.0, 7.8, 6.9]
-
- # plot()函数的第一个参数表示横坐标数据,第二个参数表示纵坐标数据
- # 第三个参数表示颜色、线型和标记样式
- # 颜色常用的值有(r/g/b/c/m/y/k/w)
- # 线型常用的值有(-/--/:/-.)
- # 标记样式常用的值有(./,/o/v/^/s/*/D/d/x/>/h/H/1/2/3/4/_/|)
- plt.plot(month, money, 'r-.v')
-
- plt.xlabel('月份', fontproperties='simhei', fontsize=14)
- plt.ylabel('营业额(万元)', fontproperties='simhei', fontsize=14)
- plt.title('烧烤店2019年营业额变化趋势图',
- fontproperties='simhei', fontsize=18)
-
- # 紧缩四周空白,扩大绘图区域可用面积
- plt.tight_layout()
-
- plt.show()

散点图(scatter diagram)又称为散点分布图,是以一个特征为横坐标,另一个特征为纵坐标,利用坐标点(散点)的分布形态反应特征间的统计关系的一种图形。
值是由在图表中的位置表示,类别是由图表中的不同标记表示,通常用于比较跨类别的数据。
matplotlib.pyplot.scatter(x,y,s=None,c=None,marker=None,alpha=None,**kwargs)


- import matplotlib.pyplot as plt
-
- # 月份和每月营业额
- month = list(range(1,13))
- money = [5.2, 2.7, 5.8, 5.7, 7.3, 9.2,
- 18.7, 15.6, 20.5, 18.0, 7.8, 6.9]
-
- # 绘制折线图,设置颜色和线型
- plt.plot(month, money, 'r-.')
- # 绘制散点图,设置颜色、符号和大小
- plt.scatter(month, money, c='b', marker='v', s=28)
-
- plt.xlabel('月份', fontproperties='simhei', fontsize=14)
- plt.ylabel('营业额(万元)', fontproperties='simhei', fontsize=14)
- plt.title('烧烤店2019年营业额变化趋势图',
- fontproperties='simhei', fontsize=18)
-
- # 紧缩四周空白,扩大绘图面积
- plt.tight_layout()
-
- plt.show()


- import matplotlib.pyplot as plt
-
- # 读取文件中的数据
- with open(r'E:\python 3.7\程序保存\CH3\商场一楼手机信号强度(1).txt') as fp:
- for line in fp:
- x, y, s = map(int, line.split(','))
- # 绘制散点图,s指大小,c指颜色,marker指符号形状
- if s < 40:
- color = 'r'
- elif s < 70:
- color = 'b'
- else:
- color = 'g'
- plt.scatter(x, y, s=s*3, c=color, marker='*')
-
- plt.xlabel('长度坐标',
- fontproperties='stkaiti', # 设置中文字体
- fontsize=10) # 设置字号
- plt.ylabel('宽\n度\n坐\n标', # 每行显示一个字
- fontproperties='stkaiti',
- fontsize=10,
- rotation='horizontal') # 设置文字方向
- plt.title('商场内信号强度',
- fontproperties='stxingkai',
- fontsize=12)
-
- plt.show()

直方图(Histogram)又称质量分布图,是统计报告图中的一种,有一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据所属列别,纵轴表示数量或者占比。
用直方图可以比较直观地看出产品质量特性的分布状态,便于判断其总体质量分布情况。直方图可以发现分布表无法发现的数据模式、样本的频率分布和总体的分布。
matplotlib.pyplot.bar(left,height,width=0.8,bottom=None,hold=None,data=None,**kwargs)


- import pandas as pd
- import matplotlib.pyplot as plt
- import matplotlib.font_manager as fm
-
- data = pd.DataFrame({'月份': [1,2,3,4,5,6,7,8,9,10,11,12],
- '男装': [51,32,58,57,30,46,38,38,40,53,58,50],
- '女装': [70,30,48,73,82,80,43,25,30,49,79,60],
- '餐饮': [60,40,46,50,57,76,70,33,70,61,49,45],
- '化妆品': [110,75,130,80,83,95,87,89,96,88,86,89],
- '金银首饰': [143,100,89,90,78,129,100,97,108,152,96,87]})
-
- # 绘制柱状图,指定月份数据作为x轴
- data.plot(x='月份', kind='bar')
- # 设置x、y轴标签和字体
- plt.xlabel('月份', fontproperties='simhei')
- plt.ylabel('营业额(万元)', fontproperties='simhei')
- # 设置图例字体
- myfont = fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf')
- plt.legend(prop=myfont)
-
- plt.show()


- import matplotlib.pyplot as plt
-
- # 月份和每月营业额
- month = list(range(1,13))
- money = [5.2, 2.7, 5.8, 5.7, 7.3, 9.2,
- 18.7, 15.6, 20.5, 18.0, 7.8, 6.9]
-
- # 绘制每个月份的营业额
- for x, y in zip(month, money):
- # 营业额越高,颜色中的红色分量越大
- # 格式字符串中的0表示不够2位时前面补0
- color = '#%02x'%int(y*10)+'6666'
- plt.bar(x, y,
- color=color, hatch='*', width=0.6,
- edgecolor='b', linestyle='--',linewidth=1.5)
- plt.text(x-0.3, y+0.2, '%.1f'%y)
-
- # 设置x、y轴标签和字体
- plt.xlabel('月份', fontproperties='simhei')
- plt.ylabel('营业额(万元)', fontproperties='simhei')
- plt.title('烧烤店营业额', fontproperties='simhei', fontsize=14)
-
- # 设置x轴刻度
- plt.xticks(month)
-
- # 设置y轴跨度
- plt.ylim(0, 22)
-
- plt.show()


- import pandas as pd
- import matplotlib.pyplot as plt
- import matplotlib.font_manager as fm
-
- fig = plt.figure(facecolor='red')
- ax = fig.gca(facecolor='#ffaaee')
- # 创建DataFrame结构
- df = pd.DataFrame({'男性':(450,800,200),
- '女性':(150,100,300)})
- # 绘制柱状图
- df.plot(kind='bar', ax=ax, color=['red','blue'])
-
- # 设置x轴刻度和文本
- plt.xticks([0,1,2],
- ['从不闯红灯', '跟从别人闯红灯', '带头闯红灯'],
- color='green',
- fontproperties='simhei', # 中文字体
- rotation=20) # 旋转刻度的文本
-
- # 设置y轴只在有数据的位置显示刻度
- plt.yticks(list(df['男性'].values) + list(df['女性'].values))
- plt.ylabel('人数', fontproperties='stkaiti', fontsize=14)
- plt.title('过马路方式', fontproperties='stkaiti', fontsize=20)
-
- # 创建和设置图例字体
- font = fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf')
- plt.legend(prop=font)
-
- plt.show()

- import matplotlib.pyplot as plt
-
- colors='bgrcmykw'
- for i in range(len(colors)):
- plt.bar(i,3*i+1,color=colors[i])
-
- plt.show()

饼图(Pie Graph)是将各项的大小与各项总和的比例显示在一张“饼”中,以“饼”的大小来确定每一项的占比。
饼图可以比较清楚地反映出部分与部分、部分与整体之间的比例关系,易于显示每组数据相对于总数的大小,而且显现方式直观。
matplotlib.pyplot.pie(x,explode=None,labels=None,colors=None,autopct=None,pctdistance=0.6,shadow=False,labeldistance=1.1,startangle=None,radius=None,...))


- from itertools import groupby
- import matplotlib.pyplot as plt
-
- # 设置图形中使用中文字体
- plt.rcParams['font.sans-serif'] = ['simhei']
-
- # 每门课程的成绩
- scores = {'数据结构':[89,70,49,87,92,84,73,71,78,81,90,37,
- 77,82,81,79,80,82,75,90,54,80,70,68,61],
- '线性代数':[70,74,80,60,50,87,68,77,95,80,79,74,
- 69,64,82,81,78,90,78,79,72,69,45,70,70],
- '英语':[83,87,69,55,80,89,96,81,83,90,54,70,79,
- 66,85,82,88,76,60,80,75,83,75,70,20],
- 'Python':[90,60,82,79,88,92,85,87,89,71,45,50,
- 80,81,87,93,80,70,68,65,85,89,80,72,75]}
-
- # 自定义分组函数,在下面的groupby()函数中使用
- def splitScore(score):
- if score>=85:
- return '优'
- elif score>=60:
- return '及格'
- else:
- return '不及格'
-
- # 统计每门课程中优、及格、不及格的人数
- # ratios的格式为{'课程名称':{'优':3, '及格':5, '不及格':1},...}
- ratios = dict()
- for subject, subjectScore in scores.items():
- ratios[subject] = {}
- # groupby()函数需要对原始分数进行排序才能正确分类
- for category, num in groupby(sorted(subjectScore), splitScore):
- ratios[subject][category] = len(tuple(num))
-
- # 创建4个子图
- fig, axs = plt.subplots(2,2)
- axs.shape = 4,
- # 依次在4个子图中绘制每门课程的饼状图
- for index, subjectData in enumerate(ratios.items()):
- # 选择子图
- plt.sca(axs[index])
- subjectName, subjectRatio = subjectData
- plt.pie(list(subjectRatio.values()), # 每个扇形对应的数值
- labels=list(subjectRatio.keys()), # 每个扇形的标签
- autopct='%1.1f%%') # 百分比显示格式
- plt.xlabel(subjectName)
- plt.legend()
- plt.gca().set_aspect('equal') # 设置纵横比相等
-
- plt.show()


- import numpy as np
- import matplotlib.pyplot as plt
-
- # 某学生的课程与成绩
- courses = ['C++', 'Python', '高数', '大学英语', '软件工程',
- '组成原理', '数字图像处理', '计算机图形学']
- scores = [80, 95, 78, 85, 45, 65, 80, 60]
-
- dataLength = len(scores) # 数据长度
-
- # angles数组把圆周等分为dataLength份
- angles = np.linspace(0, # 数组第一个数据
- 2*np.pi, # 数组最后一个数据
- dataLength, # 数组中数据数量
- endpoint=False) # 不包含终点
-
- scores.append(scores[0])
- angles = np.append(angles, angles[0]) # 闭合
- # 绘制雷达图
- plt.polar(angles, # 设置角度
- scores, # 设置各角度上的数据
- 'rv--', # 设置颜色、线型和端点符号
- linewidth=2) # 设置线宽
-
- # 设置角度网格标签
- plt.thetagrids(angles*180/np.pi,
- courses,
- fontproperties='simhei')
-
- # 填充雷达图内部
- plt.fill(angles,
- scores,
- facecolor='r',
- alpha=0.4)
-
- plt.show()


- import random
- import numpy as np
- import matplotlib.pyplot as plt
- import matplotlib.font_manager as fm
-
- # 每月支出数据
- data = {
- '蔬菜': [1350,1500,1330,1550,900,1400,980,1100,1370,1250,1000,1100],
- '水果': [400,600,580,620,700,650,860,900,880,900,600,600],
- '肉类': [480,700,370,440,500,400,360,380,480,600,600,400],
- '日用': [1100,1400,1040,1300,1200,1300,1000,1200,950,1000,900,950],
- '衣服': [650,3500,0,300,300,3000,1400,500,800,2000,0,0],
- '旅游': [4000,1800,0,0,0,0,0,4000,0,0,0,0],
- '随礼': [0,4000,0,600,0,1000,600,1800,800,0,0,1000]
- }
-
- dataLength = len(data['蔬菜']) # 数据长度
-
- # angles数组把圆周等分为dataLength份
- angles = np.linspace(0, # 数组第一个数据
- 2*np.pi, # 数组最后一个数据
- dataLength, # 数组中数据数量
- endpoint=False) # 不包含终点
-
- markers = '*v^Do'
- for col in data.keys():
- # 使用随机颜色和标记符号
- color = '#'+''.join(map('{0:02x}'.format,
- np.random.randint(0,255,3)))
- plt.polar(angles, data[col], color=color,
- marker=random.choice(markers), label=col)
-
- # 设置角度网格标签
- plt.thetagrids(angles*180/np.pi,
- list(map(lambda i:'%d月'%i, range(1,13))),
- fontproperties='simhei')
-
- # 创建和设置图例字体
- font = fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf')
- plt.legend(prop=font)
-
- plt.show()

- import numpy as np
- import matplotlib.pyplot as plt
-
-
- r=np.arange(1,6,1)
- theta=(r-1)*(np.pi/2)
-
- ax1=plt.subplot(221)
- ax2=plt.subplot(222,projection='polar')
- ax3=plt.subplot(223,projection='polar')
- ax4=plt.subplot(224,projection='polar')
-
-
- ax1.plot(theta,r,'b--D')
- ax2.plot(theta,r,linewidth=3,color='r')
- ax3.scatter(theta,r,marker='*',c='g',s=60)
- ax4.bar(theta,r)
-
- plt.show()

- import numpy as np
- import matplotlib.pyplot as plt
-
- theta=np.linspace(-np.pi,np.pi,201)
- rho=np.sin(6.0/5*theta)**2+np.cos(6*theta)**3
-
- plt.subplot(111,polar=True)
- plt.plot(theta+np.pi/6,rho)
- plt.grid(False)
- plt.yticks([])
- plt.show()
