文章目录
Matplotlib的使用
Matplotlib 是一个 Python 的 2D绘图库。通过 Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。
-
为什么学习Matplotlib
-
可让数据可视化,更直观的真实给用户。使数据更加客观、更具有说服力。
-
Matplotlib是Python的库,又是开发中常用的库
-
Matplotlib的安装
pip install matplotlib
Matplotlib的基本使用
import numpy as np
from matplotlib import pyplot as plt
x = np.arange(1,11)
y = 2 * x + 5
plt.title("Matplotlib demo")
plt.xlabel("x axis caption")
plt.ylabel("y axis caption")
plt.plot(x,y)
plt.show()
以上代码中,我们方法说明:
-
plt.title()
:设置图表的名称 -
plt.xlabel()
:设置x轴名称 -
plt.ylabel()
:设置y轴名称 -
plt.xticks(x,ticks,rotation)
:设置x轴的刻度,rotation旋转角度 -
plt.yticks()
:设置y轴的刻度 -
plt.plot()
:绘制线性图表 -
plt.show()
:显示图表 -
plt.legend()
:显示图例 -
plt.text(x,y,text)
:显示每条数据的值;x, y值的位置 -
plt.figure(name,figsize=(w,h),dpi=n)
:设置图片大小
图表中文显示
Matplotlib 默认情况不支持中文,我们可以使用以下简单的方法来解决:
首先下载字体(注意系统):https://www.fontpalace.com/font-details/SimHei/
方法1:引入字体文件
zhfont1 = matplotlib.font_manager.FontProperties(fname="SimHei.ttf")
plt.title("图表 - 测试",fontproperties=zhfont1)
方法2:使用系统文字
# 查看系统支持的字体
a=sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])
for i in a:
print(i)
在上面的代码中找到可以使用的字体,使用
plt.rcParams['font.family']=['SimHei']
1. 线性图表
- 以折线的上升或下降来表示统计数量的增减变化的统计图
- 特点:能够显示数据的变化走势,反映事物的变化情况
plt.plot(x,y,type,label)
参数:- x:x轴显示的数据
- y:y轴的值
- type:值显示的方式,具体值如下
- label:图例名称
字符 | 描述 |
---|---|
'-' | 实线样式 |
'--' | 短横线样式 |
'-.' | 点划线样式 |
':' | 虚线样式 |
'.' | 点标记 |
',' | 像素标记 |
'o' | 圆标记 |
'v' | 倒三角标记 |
'^' | 正三角标记 |
'<' | 左三角标记 |
'>' | 右三角标记 |
'1' | 下箭头标记 |
'2' | 上箭头标记 |
'3' | 左箭头标记 |
'4' | 右箭头标记 |
's' | 正方形标记 |
'p' | 五边形标记 |
'*' | 星形标记 |
'h' | 六边形标记 1 |
'H' | 六边形标记 2 |
'+' | 加号标记 |
'x' | X 标记 |
'D' | 菱形标记 |
'd' | 窄菱形标记 |
'|' | 竖直线标记 |
'_' | 水平线标记 |
- 颜色如下:
字符 | 颜色 |
---|---|
'b' | 蓝色 |
'g' | 绿色 |
'r' | 红色 |
'c' | 青色 |
'm' | 品红色 |
'y' | 黄色 |
'k' | 黑色 |
'w' | 白色 |
plt.plot(x, y,'*m')
- 代码示例:
from matplotlib import pyplot as plt
import matplotlib
def test1(): # 基本入门
# 构造数据
info = [10, 11, 10, 9, 3, 6, 8, 5, 7, 8, 12, 11]
x = range(0, 12)
x_ticks = ['{}月'.format(i) for i in range(1, 13)]
# 引入字体文件
font1 = matplotlib.font_manager.FontProperties(fname='SimHei.ttf')
# 设置x轴的标签
plt.xticks(x, x_ticks, fontproperties=font1)
plt.plot(x, info)
plt.show()
def test2(): # 设置中文
# 查看系统支持的字体
# a = sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])
# for i in a:
# print(i)
# 构造数据
info = [10, 11, 10, 9, 3, 6, 8, 5, 7, 8, 12, 11]
x = range(0, 12)
x_ticks = ['{}月'.format(i) for i in range(1, 13)]
# 设置plt的字体
plt.rcParams['font.family'] = ['SimHei']
# 设置x轴的标签
plt.xticks(x, x_ticks, rotation=45)
plt.plot(x, info)
plt.show()
def test3(): # 设置图片信息
# 构造数据
info = [10, 11, 10, 9, 3, 6, 8, 5, 7, 8, 12, 11]
x = range(0, 12)
x_ticks = ['{}月'.format(i) for i in range(1, 13)]
# 设置plt的字体
plt.rcParams['font.family'] = ['SimHei']
# 设置x轴的标签
plt.xticks(x, x_ticks, rotation=45)
plt.plot(x, info)
# 设置图标名称
plt.title('某手机年销售数据统计表(XXXX年)')
# 设置X轴说明
plt.xlabel('月份')
# 设置Y轴说明
plt.ylabel('销量(万)')
plt.show()
def test4(): # 绘画多数据与图例
# 构造数据
max_temperature = [26, 30, 31, 32, 33]
min_temperature = [12, 16, 16, 17, 18]
x = range(5)
plt.rcParams['font.family'] = ['SimHei']
x_ticks = ['星期{}'.format(i) for i in range(1, 6)]
plt.title('某年某周第N周的温度')
plt.xlabel('周')
plt.ylabel('温度:单位(℃)')
# 设置x轴标签
plt.xticks(x, x_ticks)
# 填充数据
plt.plot(x, max_temperature, label='最高温')
plt.plot(x, min_temperature, label='最低温')
# 显示图例
plt.legend(loc=2)
# 绘画
plt.show()
def test5(): # 绘画表格细节
# 构造数据
max_temperature = [26, 30, 31, 32, 33]
min_temperature = [12, 16, 16, 17, 18]
x = range(5)
plt.rcParams['font.family'] = ['SimHei']
x_ticks = ['星期{}'.format(i) for i in range(1, 6)]
plt.title('某年某周第N周的温度')
plt.xlabel('周')
plt.ylabel('温度:单位(℃)')
# 设置表格的标尺
plt.tick_params(top=False, right=False, left=False, bottom=False)
# 设置网络表格
plt.grid(alpha=0.2) # 透明度值 0-1之间
# 设置x轴标签
plt.xticks(x, x_ticks)
# 设置y轴标签
y = range(10, 35, 2)
plt.yticks(y)
fig, ax = plt.subplots()
# 取消边框
for key, spine in ax.spines.items():
# 'left', 'right', 'bottom', 'top'
if key == 'right' or key == 'top':
spine.set_visible(False)
# 设置RGB颜色
c1 =(70/255,130/255,180/255)
c2 =(0/255,255/255,0/255)
# 填充数据
plt.plot(x, max_temperature, label='最高温', linewidth=5, c=c2)
plt.plot(x, min_temperature, label='最低温', linewidth=5, c='m')
# 显示图例
plt.legend(loc=2)
# 绘画
plt.show()
if __name__ == '__main__':
test5()
2. 绘画条状图
-
排列在工作表的列或行中的数据可以绘制到中
-
特点:绘制连离散的数据,能够一眼看出各个数据的大小,可以快速统计数据之间的差别
-
bar(x,y,color,width)
函数来生成纵向条形图 -
barh(x,y,color,height)
函数来生成条形图- x 条装显示位置
- y 显示的值
- color 显示的颜色
-
爬虫爬取数据(之后的示例都是用爬取的数据)
import requests
from lxml import etree
from fake_useragent import UserAgent
import re
def get_price_data():
url = 'http://www.yihuodata.com/%E5%85%A8%E5%9B%BD%E6%88%90%E4%BA%A4%E5%9C%9F%E5%9C%B0%E6%88%90%E4%BA%A4%E5%9C%9F%E5%9C%B0%E5%9D%87%E4%BB%B7-%E6%9C%88%E5%BA%A6%E6%95%B0%E6%8D%AE.html'
headers = {'User-Agent': UserAgent().chrome}
resp = requests.get(url, headers=headers)
e = etree.HTML(resp.text)
dates = e.xpath('//tr/td[1]/text()')[2:]
nums = [float(i) for i in e.xpath('//tr/td[2]/text()')[2:]]
return dates, nums
def get_company_data():
url = 'http://www.yihuodata.com/2008%E5%B9%B4%E7%A7%81%E8%90%A5%E4%BC%81%E4%B8%9A%E8%B0%83%E6%9F%A5%E6%95%B0%E6%8D%AE-%E5%85%A8%E5%9B%BD%E7%A7%81%E8%90%A5%E4%BC%81%E4%B8%9A%E6%8A%BD%E6%A0%B7%E8%B0%83%E6%9F%A52008%E5%B9%B4%E5%BE%AE.html'
headers = {'User-Agent': UserAgent().chrome}
resp = requests.get(url, headers=headers)
e = etree.HTML(resp.text)
addrs = [a.replace('\xa0 ', '') for a in e.xpath('//tr/td[1]/text()')[2:]]
nums = [float(i) for i in e.xpath('//tr/td[2]/text()')[2:]]
return addrs, nums
def get_movie_data(num):
url = 'http://www.cbooo.cn/BoxOffice/GetDayBoxOffice?num={}'.format(num)
headers = {'User-Agent': UserAgent().chrome}
resp = requests.get(url, headers=headers)
names = re.findall(r'"MovieName":"(.+?)"', resp.text)
boxOffice = re.findall(r'"BoxOffice":"(\d+)"', resp.text)
return names, boxOffice
def get_movie_price_data():
url = 'http://www.cbooo.cn/year?year=2019'
headers = {'User-Agent': UserAgent().chrome}
resp = requests.get(url, headers=headers)
e = etree.HTML(resp.text)
prices = [int(n) for n in e.xpath('//tr/td[4]/text()')]
return prices
if __name__ == '__main__':
print(get_movie_price_data())
- 代码示例:
from matplotlib import pyplot as plt
from DataFromNet import get_company_data, get_movie_data
def test7():
# 获取数据
addrs, nums = get_company_data()
# 设置中文
plt.rcParams['font.family'] = ['SimHei']
# 设置x轴位置
x = range(6)
# 设置标题
plt.title('2008年私营企业数量')
# x轴的数据
plt.xticks(x, addrs)
# x轴的信息
plt.xlabel('地区')
# y轴的信息
plt.ylabel('户数')
# 填充数据
plt.bar(x, nums, color='red', width=0.2)
# 显示图表
plt.show()
def test8():
# 获取数据
addrs, nums = get_company_data()
# 设置中文
plt.rcParams['font.family'] = ['SimHei']
# 设置x轴位置
x = range(6)
# 设置标题
plt.title('2008年私营企业数量')
# x轴的数据
plt.yticks(x, addrs)
# x轴的信息
plt.ylabel('地区')
# y轴的信息
plt.xlabel('户数')
# 设置显示bar的值
for m, n in zip(x, nums):
plt.text(n + 1000, m, n)
# 填充数据 -- 水平条状图
plt.barh(x, nums)
# 显示图表
plt.show()
def test9(): # 多条状图的绘画
real_names = []
# 获取数据
# names, num1 = get_movie_data(-3)
# names, num2 = get_movie_data(-4)
# names, num3 = get_movie_data(-5)
# real_names = names[:3]
# real_num1 = num1[:3]
# real_num2 = num2[:3]
# real_num3 = num3[:3]
real_names = ['大侦探皮卡丘', '复仇者联盟4:终局之战', '何以为家']
real_num1 = [8414, 4024, 2088]
real_num2 = [11526, 5605, 2490]
real_num3 = [7675, 2863, 1311]
# print(real_names, real_num1, real_num2, real_num3)
# 设置中文
plt.rcParams['font.family'] = ['SimHei']
plt.title('电影票房前三排名统计(3天)')
plt.xlabel('天数')
plt.ylabel('票房数')
# 设置x轴位置
x1_pos = list(range(3))
x2_pos = [i + 0.3 for i in x1_pos]
x3_pos = [i + 2 * 0.3 for i in x1_pos]
print(x1_pos, x2_pos, x3_pos)
# 设置x轴标签
x_ticks = ['第{}天'.format(i) for i in range(1, 4)]
plt.xticks(x2_pos, x_ticks)
# 设置条状图宽度
width = 0.3
# 填充数据
plt.bar(x1_pos, real_num3, width=width,label='大侦探皮卡丘')
plt.bar(x2_pos, real_num2, width=width,label='复仇者联盟4:终局之战')
plt.bar(x3_pos, real_num1, width=width,label='何以为家')
# 显示图例
plt.legend()
# 显示图标
plt.show()
if __name__ == '__main__':
test9()
3. 绘画直方图
-
由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据范围,纵轴表示分布情况。
-
特点:绘制连续性的数据,展示一组或多组数据的分布状况并统计。
-
注意:拿到数据来统计,而不是直接拿统计好的数据。
-
概念:
- 组距:每组数据的分割区域,例如1-5一组5-10一组。我们可以称数据的组距为5。
- 组数:(最大数据-最小数据)/组距 一般会100条数据可分5-12组。
-
hist(data,bins,normed)
:-
data:所有的数据
-
bins:分几组
-
normed:y轴是否显示成百分比
-
plt.hist(data,bins)
- 代码示例:
from matplotlib import pyplot as plt
def test10():
# 获取数据
data = [45, 49, 42, 42, 36, 37, 31, 38, 35, 39, 43, 33, 34, 36, 35, 36, 34, 32, 36, 32, 37, 33, 32, 38, 35]
# 设置组距
bin_width = 2
# 设置分组
bin_count = int((max(data) - min(data)) / bin_width)
# 设置x轴标签位置
x = range(bin_count)
x_ticks = range(31, 50, 2)
# 设置x轴标签的值
plt.xticks(x_ticks)
# 填充数据
plt.hist(data, bin_count)
# 显示图表
plt.show()
if __name__ == '__main__':
test10()
4. 绘画散点图
- 用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式
plt.scatter(x,info)
plt.plot(x,a,'o')
-
特点:判断变量之间是否存在在数量关联走势,展示离群点分布规律。
-
代码示例:
from matplotlib import pyplot as plt
from DataFromNet import get_price_data
# 从网上爬的数据
def test6():
# 获取数据
dates, nums = get_price_data()
# 中文字体
plt.rcParams['font.family'] = ['SimHei']
x = range(50)
# 显示刻度
plt.xticks(x[::2], dates[:50:2], rotation=45)
# 填充数据
plt.scatter(x, nums[:50])
# 显示标题
plt.title('全国成交土地成交土地均价 (月度数据)')
# 显示x轴说明
plt.xlabel('时间频率(月)')
# 显示y轴说明
plt.ylabel('元/平方米')
# 显示图表
plt.show()
if __name__ == '__main__':
test6()
5. 绘画子图
subplot()
函数允许你在同一图中绘制不同的东西
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(19680801)
data = np.random.randn(2, 100)
fig, axs = plt.subplots(2, 2, figsize=(7, 7))
axs[0, 0].hist(data[0])
axs[1, 0].scatter(data[0], data[1])
axs[0, 1].plot(data[0], data[1])
axs[1, 1].hist2d(data[0], data[1])
plt.show()
成交土地均价 (月度数据)')
# 显示x轴说明
plt.xlabel('时间频率(月)')
# 显示y轴说明
plt.ylabel('元/平方米')
# 显示图表
plt.show()
if __name__ == '__main__':
test6()
5. 绘画子图
subplot()
函数允许你在同一图中绘制不同的东西
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(19680801)
data = np.random.randn(2, 100)
fig, axs = plt.subplots(2, 2, figsize=(7, 7))
axs[0, 0].hist(data[0])
axs[1, 0].scatter(data[0], data[1])
axs[0, 1].plot(data[0], data[1])
axs[1, 1].hist2d(data[0], data[1])
plt.show()