2020-08-02--数据分析-Matplotlib
Matplotlib 是一个 Python 的 2D绘图库,通过 Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。
- 用于创建出版质量图表的绘图工具库
- 最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建
- 目的是为Python构建一个Matlab式的绘图接口
- pyploy模块包含了常用的matplotlib API函
Matplotlib
# 导入相关模块
import matplotlib.pyplot as plt
import numpy as np
1.简单的图形
正弦图:
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
arr =np.linspace(0,2*np.pi,50)
sinarr = np.sin(arr)
# 描点,展示
plt.plot(arr,sinarr)
# y轴数据*2
plt.plot(arr,sinarr*2)
plt.show()
运行:
plt.plot(data,linewidth=int):linewidth设置线条的粗细程度。
绘制出图形之后,我们可以自己调整更多的样式,比如颜色、点、线。
plt.plot(x, y, 'y*-')
plt.plot(x, y * 2, 'm--')
plt.show()
运行:
可以看到,设置样式时,就是增加了一个字符串参数,比如 'y-' ,其中 y 表示黄色, 表示 星标的点,- 表示实线。
这里列举一些常见的颜色表示方式:
颜色 | 表示方式 |
---|---|
蓝色 | b |
绿色 | g |
红色 | r |
青色 | c |
品红 | m |
黄色 | y |
黑色 | k |
白色 | w |
常见的点的表示方式:
点的类型 | 表示方式 |
---|---|
点 | . |
像素 | , |
圆 | o |
方形 | s |
三角形 | ^ |
常见的线的表示方式:
线的类型 | 表示方式 |
---|---|
直线 | - |
虚线 | -- |
点线 | : |
点划线 | -. |
2.常用设置
1.设置 figure
你可以认为Matplotlib绘制的图形都在一个默认的 figure 框中,就是控制图形的大小
在描点之前设置figure的大小:
plt.figure(figsize=(x,y))
plt.figure(figsize=(6, 3))
# 描点,展示
plt.plot(arr,sinarr,linewidth=3)
# y轴数据*2
plt.plot(arr,sinarr*2)
plt.show()
2.设置标题
plt.title('标题文本',fontsize=int)
plt.title('sin(arr)&2sin(arr)',fontsize=12)
# 描点,展示
plt.plot(arr,sinarr,linewidth=3)
# y轴数据*2
plt.plot(arr,sinarr*2)
plt.show()
解决中文显示和负号显示问题:
在代码中设置两个值即可解决```
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
3.设置坐标轴
plt.xlim((0, np.pi + 1)) # 设置x轴范围
plt.ylim((-3, 3)) # 设置y轴范围
plt.xlabel('X') # 设置x轴显示标签内容
plt.ylabel('Y') # 设置y轴显示标签内容
通过 xlim 和 ylim 来设限定轴的范围,通过 xlabel 和 ylabel 来设置轴的名称。
也可以通过 xticks 和 yticks 来设置轴的刻度。
plt.xticks((0, np.pi * 0.5, np.pi, np.pi * 1.5, np.pi * 2))
但是如果数据分布过于分散,那么刻度也会变的很多,可以通过numpy创建出一个数组,来进行设置刻度:
xt = np.linspace(0,np.pi*2,4)
plt.xticks(xt)
4.设置 label 和 legend
label 和 legend 的目的就是为了区分出图形中每个数据对应的图形名称-----图形标记。
# 描点,展示
plt.plot(arr,sinarr,label="sin(x)")
# y轴数据*2
plt.plot(arr,sinarr*2,label="2sin(x)")
plt.legend(loc='best') # 放在最佳位置
plt.show()
5.添加注释
有时候我们需要对特定的点进行标注,我们可以使用 plt.annotate 函数来实现。
这里我们要标注的点是 (π, 0)。
我们也可以使用 plt.text 函数来添加注释。
# 描点,展示
plt.plot(arr,sinarr,label="sin(x)")
# y轴数据*2
plt.plot(arr,sinarr*2,label="2sin(x)")
x0 = np.pi
y0 = 0
# 标注点
plt.scatter(x0,y0,s=50)
plt.annotate('sin(np.pi)=%s' % y0, xy=(np.pi, 0), xycoords='data', xytext=(+15, -15),
textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=.2"))
plt.text(0.5, -0.25, "sin(np.pi) = 0", fontdict={'size': 16, 'color': 'r'})
plt.legend(loc='best')
plt.show()
1.plt.scatter(x0,y0,s=50,c='r') 坐标, s:标注点大小,c:点的颜色
- annotate 函数的参数,做一个简单解释:
- 'sin(np.pi)=%s' % y0 代表标注的内容,可以通过字符串 %s 将 y0 的值传入字符串;
- 参数 xycoords='data' 是说基于数据的值来选位置;
- xytext=(+30, -30) 和 textcoords='offset points' 表示对于标注位置的描述 和 xy 偏差值,即文字标注位置是 xy 位置向右移动 30,向下移动30;
- arrowprops 是对图中箭头类型和箭头弧度的设置,需要用 dict 形式传入。
3.plt.text(0.5, -0.25, "sin(np.pi) = 0", fontdict={'size': 16, 'color': 'r'})参数:
- 0.5,-0.25是坐标
- "sin(np.pi) = 0"是显示文字
- fontdict={'size': 16, 'color': 'r'}是文字的大小颜色,字典类型。
6.使用子图
有时候我们需要将多张子图展示在一起,可以使用 subplot() 实现。即在调用 plot() 函数之前需要先调用 subplot() 函数。该函数的第一个参数代表子图的总行数,第二个参数代表子图的总列数,第三个参数代表活跃区域,也就是要展示的区域。
ax1 = plt.subplot(2, 2, 1) # (行,列,活跃区)
plt.plot(arr, np.sin(arr), 'r')
ax2 = plt.subplot(2, 2, 2, sharey=ax1) # 与 ax1 共享y轴,与ax1在一横排
plt.plot(arr, 2 * np.sin(arr), 'g')
ax3 = plt.subplot(2, 2, 3)
plt.plot(arr, np.cos(arr), 'b')
ax4 = plt.subplot(2, 2, 4, sharey=ax3) # 与 ax3 共享y轴,与ax3在一横排
plt.plot(arr, 2 * np.cos(arr), 'y')
plt.show()
上面的 subplot(2, 2, x) 表示将图像窗口分为 2 行 2 列。x 表示当前子图所在的活跃区。活跃区域的中不能大于行列的乘积。
可以看到,上面的每个子图的大小都是一样的。有时候我们需要不同大小的子图。
比如将上面第一张子图完全放置在第一行,其他的子图都放在第二行。
# 将创就分为两行一列,该图形占第一个位置
ax1 = plt.subplot(2, 1, 1) # (行,列,活跃区)
plt.plot(x, np.sin(x), 'r')
# 将整个窗口分为两行三列,由于上边图形已经占了第一行的三个位置了,所以,该图形的活跃区域为4,其次为5,6
ax2 = plt.subplot(2, 3, 4)
plt.plot(x, 2 * np.sin(x), 'g')
ax3 = plt.subplot(2, 3, 5, sharey=ax2)
plt.plot(x, np.cos(x), 'b')
ax4 = plt.subplot(2, 3, 6, sharey=ax2)
plt.plot(x, 2 * np.cos(x), 'y')
plt.show()
简单解释下,plt.subplot(2, 1, 1) 将图像窗口分为了 2 行 1 列, 当前活跃区为 1。
使用 plt.subplot(2, 3, 4) 将整个图像窗口分为 2 行 3 列, 当前活跃区为 4。
解释下为什么活跃区为 4,因为上一步中使用 plt.subplot(2, 1, 1) 将整个图像窗口分为 2 行 1 列, 第1个小图占用了第1个位置, 也就是整个第1行. 这一步中使用 plt.subplot(2, 3, 4)将整个图像窗口分为 2 行 3 列, 于是整个图像窗口的第1行就变成了3列, 也就是成了3个位置, 于是第2行的第1个位置是整个图像窗口的第4个位置。
3.常用图形
这里带大家画一些常见的示例图。
1. 散点图
首先来看下如何绘制散点图。
# 获取随机描点的x,y坐标
x=np.random.random(50)
y=np.random.random(50)
# 生成随机每个点的大小
size = np.random.rand(k) * 50
# 获取随机color
cc = np.arctan2(x,y)
print(cc)
# 描点,x,y:坐标 c:颜色
plt.scatter(x,y,c=cc)
plt.colorbar() # 添加颜色栏
plt.show()
上面我们首先生成了要绘制的数据的点x 和 y,接下来为每个数据点生成控制大小的数组 size,然后未每个数据点生成控制颜色的数组 colour。最后通过 colorbar() 来增加一个颜色栏。
2.柱状图
柱状图我们经常会用到,我们来看下如何画出柱状图,并在图上标注出数据对应的数值。
# 获取x,y坐标
x = np.arange(7)
y = np.random.random(7)*20
# 画图
plt.bar(x,y)
# 添加文字和数值信息
for x,y in zip(x,y):
plt.text(x,y,'%.2f' % y, ha='center', va='bottom')
plt.show()
生成数据 x 和 y 之后,调用 plt.bar 函数绘制出柱状图,然后通过 plt.text 标注数值,设置参数 ha='center' 横向居中对齐,设置 va='bottom'纵向底部(顶部)对齐。
3.折线图
解决中文乱码问题:
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
折线图:
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
x = ['北京', '上海', '深圳', '广州']
y = [60000, 58000, 50000, 52000]
plt.plot(x, y)
plt.show()
4.数据加载和简单的数据探索
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn import datasets #数据集
1.数据获取
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets # 获取sklearn中的鸢尾花数据集
# 获取iris数据集
df = datasets.load_iris()
# print(df)
# 获取key集合,(返回该数据集中的所有属性名)
ks = df.keys()
print(type(ks),ks)
# <class 'dict_keys'> dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename'])
# data:主体数据
fit_data = df.data
print(fit_data,fit_data.shape) # (150,4)
# target:对应鸢尾花的分类
fit_label = df.target
print(fit_label,fit_label.shape) # (150,)
# target_names:target对应的名称表示
fit_label_name = df.target_names
print(fit_label_name) # ['setosa' 'versicolor' 'virginica']
# feature_names:获取数据集数据data中每列对应的名称
fit_fea = df.feature_names
print(fit_fea)
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
# filename:本地文件
fname = df.filename
print(fname) # 返回路径
# E:\Anaconda\lib\site-packages\sklearn\datasets\data\iris.csv
# DESCR:数据文档
Iris Plants Database
====================
Notes
-----
Data Set Characteristics:
:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive attributes and the class
:Attribute Information:
- sepal length in cm
- sepal width in cm
- petal length in cm
- petal width in cm
- class:
- Iris-Setosa
- Iris-Versicolour
- Iris-Virginica
:Summary Statistics:
============== ==== ==== ======= ===== ====================
Min Max Mean SD Class Correlation
============== ==== ==== ======= ===== ====================
sepal length: 4.3 7.9 5.84 0.83 0.7826
sepal width: 2.0 4.4 3.05 0.43 -0.4194
petal length: 1.0 6.9 3.76 1.76 0.9490 (high!)
petal width: 0.1 2.5 1.20 0.76 0.9565 (high!)
============== ==== ==== ======= ===== ====================
:Missing Attribute Values: None
:Class Distribution: 33.3% for each of 3 classes.
:Creator: R.A. Fisher
:Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
:Date: July, 1988
This is a copy of UCI ML iris datasets.
http://archive.ics.uci.edu/ml/datasets/Iris
The famous Iris database, first used by Sir R.A Fisher
This is perhaps the best known database to be found in the
pattern recognition literature. Fisher's paper is a classic in the field and
is referenced frequently to this day. (See Duda & Hart, for example.) The
data set contains 3 classes of 50 instances each, where each class refers to a
type of iris plant. One class is linearly separable from the other 2; the
latter are NOT linearly separable from each other.
References
----------
- Fisher,R.A. "The use of multiple measurements in taxonomic problems"
Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions to
Mathematical Statistics" (John Wiley, NY, 1950).
- Duda,R.O., & Hart,P.E. (1973) Pattern Classification and Scene Analysis.
(Q327.D83) John Wiley & Sons. ISBN 0-471-22361-1. See page 218.
- Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System
Structure and Classification Rule for Recognition in Partially Exposed
Environments". IEEE Transactions on Pattern Analysis and Machine
Intelligence, Vol. PAMI-2, No. 1, 67-71.
- Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule". IEEE Transactions
on Information Theory, May 1972, 431-433.
- See also: 1988 MLC Proceedings, 54-64. Cheeseman et al"s AUTOCLASS II
conceptual clustering system finds 3 classes in the data.
- Many, many more ...
# 数据集
iris.data
array([[5.1, 3.5, 1.4, 0.2],
[4.9, 3. , 1.4, 0.2],
[4.7, 3.2, 1.3, 0.2],
[4.6, 3.1, 1.5, 0.2],
[5. , 3.6, 1.4, 0.2],
[5.4, 3.9, 1.7, 0.4],
[4.6, 3.4, 1.4, 0.3],
[5. , 3.4, 1.5, 0.2],
[4.4, 2.9, 1.4, 0.2],
[4.9, 3.1, 1.5, 0.1],
[5.4, 3.7, 1.5, 0.2],
[4.8, 3.4, 1.6, 0.2],
[4.8, 3. , 1.4, 0.1],
[4.3, 3. , 1.1, 0.1],
[5.8, 4. , 1.2, 0.2],
[5.7, 4.4, 1.5, 0.4],
[5.4, 3.9, 1.3, 0.4],
[5.1, 3.5, 1.4, 0.3],
[5.7, 3.8, 1.7, 0.3],
[5.1, 3.8, 1.5, 0.3],
[5.4, 3.4, 1.7, 0.2],
[5.1, 3.7, 1.5, 0.4],
[4.6, 3.6, 1. , 0.2],
[5.1, 3.3, 1.7, 0.5],
[4.8, 3.4, 1.9, 0.2],
[5. , 3. , 1.6, 0.2],
[5. , 3.4, 1.6, 0.4],
[5.2, 3.5, 1.5, 0.2],
[5.2, 3.4, 1.4, 0.2],
[4.7, 3.2, 1.6, 0.2],
[4.8, 3.1, 1.6, 0.2],
[5.4, 3.4, 1.5, 0.4],
[5.2, 4.1, 1.5, 0.1],
[5.5, 4.2, 1.4, 0.2],
[4.9, 3.1, 1.5, 0.1],
[5. , 3.2, 1.2, 0.2],
[5.5, 3.5, 1.3, 0.2],
[4.9, 3.1, 1.5, 0.1],
[4.4, 3. , 1.3, 0.2],
[5.1, 3.4, 1.5, 0.2],
[5. , 3.5, 1.3, 0.3],
[4.5, 2.3, 1.3, 0.3],
[4.4, 3.2, 1.3, 0.2],
[5. , 3.5, 1.6, 0.6],
[5.1, 3.8, 1.9, 0.4],
[4.8, 3. , 1.4, 0.3],
[5.1, 3.8, 1.6, 0.2],
[4.6, 3.2, 1.4, 0.2],
[5.3, 3.7, 1.5, 0.2],
[5. , 3.3, 1.4, 0.2],
[7. , 3.2, 4.7, 1.4],
[6.4, 3.2, 4.5, 1.5],
[6.9, 3.1, 4.9, 1.5],
[5.5, 2.3, 4. , 1.3],
[6.5, 2.8, 4.6, 1.5],
[5.7, 2.8, 4.5, 1.3],
[6.3, 3.3, 4.7, 1.6],
[4.9, 2.4, 3.3, 1. ],
[6.6, 2.9, 4.6, 1.3],
[5.2, 2.7, 3.9, 1.4],
[5. , 2. , 3.5, 1. ],
[5.9, 3. , 4.2, 1.5],
[6. , 2.2, 4. , 1. ],
[6.1, 2.9, 4.7, 1.4],
[5.6, 2.9, 3.6, 1.3],
[6.7, 3.1, 4.4, 1.4],
[5.6, 3. , 4.5, 1.5],
[5.8, 2.7, 4.1, 1. ],
[6.2, 2.2, 4.5, 1.5],
[5.6, 2.5, 3.9, 1.1],
[5.9, 3.2, 4.8, 1.8],
[6.1, 2.8, 4. , 1.3],
[6.3, 2.5, 4.9, 1.5],
[6.1, 2.8, 4.7, 1.2],
[6.4, 2.9, 4.3, 1.3],
[6.6, 3. , 4.4, 1.4],
[6.8, 2.8, 4.8, 1.4],
[6.7, 3. , 5. , 1.7],
[6. , 2.9, 4.5, 1.5],
[5.7, 2.6, 3.5, 1. ],
[5.5, 2.4, 3.8, 1.1],
[5.5, 2.4, 3.7, 1. ],
[5.8, 2.7, 3.9, 1.2],
[6. , 2.7, 5.1, 1.6],
[5.4, 3. , 4.5, 1.5],
[6. , 3.4, 4.5, 1.6],
[6.7, 3.1, 4.7, 1.5],
[6.3, 2.3, 4.4, 1.3],
[5.6, 3. , 4.1, 1.3],
[5.5, 2.5, 4. , 1.3],
[5.5, 2.6, 4.4, 1.2],
[6.1, 3. , 4.6, 1.4],
[5.8, 2.6, 4. , 1.2],
[5. , 2.3, 3.3, 1. ],
[5.6, 2.7, 4.2, 1.3],
[5.7, 3. , 4.2, 1.2],
[5.7, 2.9, 4.2, 1.3],
[6.2, 2.9, 4.3, 1.3],
[5.1, 2.5, 3. , 1.1],
[5.7, 2.8, 4.1, 1.3],
[6.3, 3.3, 6. , 2.5],
[5.8, 2.7, 5.1, 1.9],
[7.1, 3. , 5.9, 2.1],
[6.3, 2.9, 5.6, 1.8],
[6.5, 3. , 5.8, 2.2],
[7.6, 3. , 6.6, 2.1],
[4.9, 2.5, 4.5, 1.7],
[7.3, 2.9, 6.3, 1.8],
[6.7, 2.5, 5.8, 1.8],
[7.2, 3.6, 6.1, 2.5],
[6.5, 3.2, 5.1, 2. ],
[6.4, 2.7, 5.3, 1.9],
[6.8, 3. , 5.5, 2.1],
[5.7, 2.5, 5. , 2. ],
[5.8, 2.8, 5.1, 2.4],
[6.4, 3.2, 5.3, 2.3],
[6.5, 3. , 5.5, 1.8],
[7.7, 3.8, 6.7, 2.2],
[7.7, 2.6, 6.9, 2.3],
[6. , 2.2, 5. , 1.5],
[6.9, 3.2, 5.7, 2.3],
[5.6, 2.8, 4.9, 2. ],
[7.7, 2.8, 6.7, 2. ],
[6.3, 2.7, 4.9, 1.8],
[6.7, 3.3, 5.7, 2.1],
[7.2, 3.2, 6. , 1.8],
[6.2, 2.8, 4.8, 1.8],
[6.1, 3. , 4.9, 1.8],
[6.4, 2.8, 5.6, 2.1],
[7.2, 3. , 5.8, 1.6],
[7.4, 2.8, 6.1, 1.9],
[7.9, 3.8, 6.4, 2. ],
[6.4, 2.8, 5.6, 2.2],
[6.3, 2.8, 5.1, 1.5],
[6.1, 2.6, 5.6, 1.4],
[7.7, 3. , 6.1, 2.3],
[6.3, 3.4, 5.6, 2.4],
[6.4, 3.1, 5.5, 1.8],
[6. , 3. , 4.8, 1.8],
[6.9, 3.1, 5.4, 2.1],
[6.7, 3.1, 5.6, 2.4],
[6.9, 3.1, 5.1, 2.3],
[5.8, 2.7, 5.1, 1.9],
[6.8, 3.2, 5.9, 2.3],
[6.7, 3.3, 5.7, 2.5],
[6.7, 3. , 5.2, 2.3],
[6.3, 2.5, 5. , 1.9],
[6.5, 3. , 5.2, 2. ],
[6.2, 3.4, 5.4, 2.3],
[5.9, 3. , 5.1, 1.8]])
# 形状
iris.data.shape
(150, 4)
# 每一列的意思
iris.feature_names
['sepal length (cm)',
'sepal width (cm)',
'petal length (cm)',
'petal width (cm)']
# 每一个样本(鸢尾花)对应的类型
iris.target
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
iris.target.shape
(150,)
# 0,1,2对应的名字
iris.target_names
array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
总结:也就是说在这个数据集中,鸢尾花一共分为3种,不同的名称,分类的依据是四个参数,这些参数的数据就在data中。
2.数据可视化
前两行数据展示:
# 通过数据集中的所有行的头两列数据,绘制散点图
fit_data_2 = fit_data[:,:2]
# 分类标识,需要将三种不同类型的鸢尾花区分展示
fit_target = fit_label
for type,color,label in [(0,'green','+'),(1,'red','o'),(2,'blue','*')]:
# 根据花萼的长度和宽度,绘制散点,区分不同的分类
# 参数:x,y坐标
plt.scatter(fit_data_2[fit_target==type,0],fit_data_2[fit_target==type,1],marker=label,color=color)
plt.show()
显示:
后两行数据展示:
'''数据可视化'''
# 通过数据集中的所有行的头两列数据,绘制散点图
fit_data_2 = fit_data[:,2:]
# 分类标识,需要将三种不同类型的鸢尾花区分展示
fit_target = fit_label
for type,color,label in [(0,'green','+'),(1,'red','o'),(2,'blue','*')]:
# 根据花萼的长度和宽度,绘制散点,区分不同的分类
# 参数:x,y坐标
plt.scatter(fit_data_2[fit_target==type,0],fit_data_2[fit_target==type,1],marker=label,color=color)
plt.show()
显示: