实用Python程序设计MOOC-第十一章数据分析和展示

实用Python程序设计MOOC-第十一章数据分析和展示

[TOC]

实用Python程序设计MOOC-第十一章数据分析和展示

多维数组库numpy

numpy简介

  • 多维数组库,创建多维数组很方便,可以替代多维列表
  • 速度比多维列表快
  • 支持向量和矩阵的各种数学运算
  • 所有元素类型必须相同
1
pip install numpy 安装

numpy创建数组的函数

函数 功能
array(x) 根据列表或元组x创建数组
arange(x,y,i) 创建一维数组, 元素等价于range(x,y,i)
linespace(x,y,n) 创建一个由区间[x,y]的n-1等分点构成的一维数组,包含x和y
random.randint(…) 创建一个元素为随机整数的数组
zeros(n) 创建一个元素全为0.0的长度为n数组
ones(n) 创建一个元素全为1.0的长度为n数组

numpy创建数组示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np #以后numpy简写为np
print(np.array([1,2,3])) #>>[1 2 3]
print(np.arange(1,9,2)) #>>[1 3 5 7] 等差数列[1,9)
print(np.linspace(1,10,4)) #>>[ 1. 4. 7. 10.] 等分数列

print(np.random.randint(10,20,[2,3])) #[10,20) 2行3列的数组
#>>[[12 19 12]
#>> [19 13 10]]

print(np.random.randint(10,20,5)) #>>[12 19 19 10 13]
a = np.zeros(3)
print(a) #>>[ 0. 0. 0.]
print(list(a)) #>>[0.0, 0.0, 0.0]
a = np.zeros((2,3),dtype=int) #创建一个2行3列的元素都是整数0的数组

numpy数组常用属性和函数

属性或函数 含义或功能
dtype 数组元素的类型
ndim 数组是几维的
shape 数组每一维的长度
size 数组元素个数
argwhere(…) 查找元素
tolist() 转换为list
min() 求最小元素
max() 求最大元素
reshape(…) 改变数组的形状
flatten() 转换成一维数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
b = np.array([i for i in range(12)])
#b是[ 0 1 2 3 4 5 6 7 8 9 10 11]
a = b.reshape((3,4)) #转换成3行4列的数组, b不变
print(len(a)) #>>3 a有3行
print(a.size) #>>12 a的元素个数是12
print(a.ndim) #>>2 a是2维的
print(a.shape) #>>(3, 4) a是3行4列
print(a.dtype) #>>int32 a的元素类型是32位的整数
L = a.tolist() #转换成列表,a不变
print(L)
#>>[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
b = a.flatten() #转换成一维数组
print(b) #>>[ 0 1 2 3 4 5 6 7 8 9 10 11]

numpy数组元素增删

函数 功能
append(x,y) 若y是数组、列表或元组,就将y的元素添加进数组x得新数组。否则将y本身添加进数组x得新数组
concatenate(…) 拼接多个数组或列表,”axis=0”行增加,”axis=1”列增加
delete(…) 删除数组元素得新数组

numpy数组一旦生成,元素就不能增删。 上面函数返回一个新的数组。

numpy添加数组元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
a = np.array((1, 2, 3)) #a是[1 2 3]
b = np.append(a, 10) #a不会发生变化
print(b) #>>[ 1 2 3 10]

print(np.append(a, [10, 20])) #>>[ 1 2 3 10 20]

c = np.zeros((2, 3),dtype=int) #c是2行3列的全0数组
print(np.append(a, c)) #>>[1 2 3 0 0 0 0 0 0]
print(np.concatenate((a, [10, 20], a)))
#>>[ 1 2 3 10 20 1 2 3]

print(np.concatenate((c, np.array([[10, 20, 30]]))))
#c拼接一行[10,20,30]得新数组
#>>[[ 0 0 0]
#>> [ 0 0 0]
#>> [10 20 30]]

print(np.concatenate((c,np.array([[1, 2], [10, 20]])), axis=1))
#c的第0行拼接了1,2两个元素、第1行拼接了10,20两个新元素后得到新数组
#>>[[ 0 0 0 1 2]
#>> [ 0 0 0 10 20]]

numpy删除数组元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
a = np.array((1,2,3,4))
b = np.delete(a,1) #删除a中下标为1的元素,a不会改变
print(b) #>>[1 3 4]
b = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(np.delete(b,1,axis=0)) #删除b的第1行得新数组
#>>[[ 1 2 3 4]
#>> [ 9 10 11 12]]
print(np.delete(b,1,axis=1)) #删除b的第1列得新数组
#>>[[ 1 3 4]
#>> [ 5 7 8]
#>> [ 9 11 12]]
print(np.delete(b,[1,2],axis=0)) #删除b的第1行和第2行得新数组
#>>[[1 2 3 4]]
print(np.delete(b,[1,3],axis=1)) #删除b的第1列和第3列得新数组
#>>[[ 1 3]
#>> [ 5 7]
#>> [ 9 11]]

在numpy数组中查找元素

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
a = np.array((1,2,3,5,3,4))
pos = np.argwhere(a==3) #pos是[[2] [4]]

a = np.array([[1,2,3],[4,5,2]])
print(2 in a) #>>True

pos = np.argwhere(a==2) #pos是[[0 1] [1 2]]
b = a[a>2] #抽取a中大于2的元素形成一个一维数组
print(b) #>>[3 4 5]
a[a > 2] = -1 #a变成[[ 1 2 -1] [-1 -1 2]]

numpy数组的数学运算

1
2
3
4
5
6
7
8
import numpy as np
a = np.array((1,2,3,4))
b = a + 1
print(b) #>>[2 3 4 5]
print(a*b) #>>[ 2 6 12 20] a,b对应元素相乘
print(a+b) #>>[3 5 7 9] a,b对应元素相加
c = np.sqrt(a*10) #a*10是[10 20 30 40]
print(c) #>>[ 3.16227766 4.47213595 5.47722558 6.32455532]

numpy数组的切片

numpy数组的切片是“视图”,
是原数组的一部分,而非一部分的拷贝
对视图的修改会影响原数组

1
2
3
4
5
6
7
8
9
10
import numpy as np
a = np.arange(8) #a是[0 1 2 3 4 5 6 7]
b = a[3:6] #注意,b是a的一部分
print(b) #>>[3 4 5]
c = np.copy(a[3:6]) #c是a的一部分的拷贝
b[0] = 100 #会修改a
print(a) #>>[ 0 1 2 100 4 5 6 7]
print(c) #>>[3 4 5] c不受b影响
a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
b = a[1:3,1:4] #b是>>[[ 6 7 8] [10 11 12]]

数据分析库pandas

pandas 简介

  • 核心功能是在二维表格上做各种操作,如增删、修改、 求一列数据的和、方差、中
    位数、平均数等
  • 需要numpy支持
  • 如果有openpyxl或xlrd或xlwt支持,还可以读写excel文档。
  • 最关键的类: DataFrame,表示二维表格
1
pip install pandas

pandas的重要类: Series

Series是一维表格,每个元素带标签且有下标,兼具列表和字典的访问形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
s = pd.Series(data=[80,90,100],index=['语文','数学','英语'])
for x in s: #>>80 90 100
print(x,end=" ")
print("")
print(s['语文'],s[1]) #>>80 90 标签和序号都可以作为下标来访问元素
print(s[0:2]['数学']) #>>90 s[0:2]是切片
print(s['数学':'英语'][1]) #>>100
for i in range(len(s.index)): #>>语文 数学 英语
print(s.index[i],end = " ")

s['体育'] = 110 #在尾部添加元素,标签为'体育',值为110
s.pop('数学') #删除标签为'数学’的元素
s2 = s.append(pd.Series(120,index = ['政治'])) #不改变s
print(s2['语文'],s2['政治']) #>>80 120
print(list(s2)) #>>[80, 100, 110, 120]

print(s.sum(),s.min(),s.mean(),s.median())
#>>290 80 96.66666666666667 100.0 输出和、最小值、平均值、中位数
print(s.idxmax(),s.argmax()) #>>体育 2 输出最大元素的标签和下标

切片是视图,是原来数据的一部分,修改了视图也会影响原来数据的变化。

DataFrame的构造和访问

DataFrame是带行列标签的二维表格,的每一列都是一个Series

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
pd.set_option('display.unicode.east_asian_width',True)
#输出对齐方面的设置
scores = [['男',108,115,97],['女',115,87,105],['女',100,60,130],
['男',112,80,50]]
names = ['刘一哥','王二姐','张三妹','李四弟']
courses = ['性别','语文','数学','英语']
df = pd.DataFrame(data = scores, index = names, columns = courses)
print(df)

print(df.values[0][1],type(df.values))#>>108 <class 'numpy.ndarray'>
print(list(df.index)) #>>['刘一哥', '王二姐', '张三妹', '李四弟']
print(list(df.columns)) #>>['性别', '语文', '数学', '英语']

print(df.index[2],df.columns[2]) #>>张三妹 数学
s1 = df['语文'] #s1是个Series,代表'语文'那一列
print(s1['刘一哥'],s1[0]) #>>108 108 刘一哥语文成绩
print(df['语文']['刘一哥']) #>>108 列索引先写
s2 = df.loc['王二姐'] #s2也是个Series,代表“王二姐”那一行
print(s2['性别'],s2['语文'],s2[2])
#>>女 115 87 王二姐的性别、语文和数学分数
1
2
3
4
5
6
7
8
9
10
11
12
       性别  语文  数学  英语
刘一哥 男 108 115 97
王二姐 女 115 87 105
张三妹 女 100 60 130
李四弟 男 112 80 50
108 <class 'numpy.ndarray'>
['刘一哥', '王二姐', '张三妹', '李四弟']
['性别', '语文', '数学', '英语']
张三妹 数学
108 108
108
女 115 87

DataFrame的切片和统计

1
2
3
4
5
6
7
8
#DataFrame的切片:
#iloc[行选择器, 列选择器] 用下标做切片
#loc[行选择器, 列选择器] 用标签做切片
#DataFrame的切片是视图

df2 = df.iloc[1:3] #行切片,是视图,选1,2两行
df2 = df.loc['王二姐':'张三妹'] #和上一行等价
print(df2)
1
2
3
       性别  语文  数学  英语
王二姐 女 115 87 105
张三妹 女 100 60 130
1
2
3
df2 = df.iloc[:,0:3] #列切片(是视图),选0、 1、 2三列
df2 = df.loc[:,'性别':'数学'] #和上一行等价
print(df2)
1
2
3
4
5
       性别  语文  数学
刘一哥 男 108 115
王二姐 女 115 87
张三妹 女 100 60
李四弟 男 112 80
1
2
3
df2 = df.iloc[:2,[1,3]] #行列切片,只取第一列和第三列
df2 = df.loc[:'王二姐',['语文','英语']] #和上一行等价
print(df2)
1
2
3
        语文  英语
刘一哥 108 97
王二姐 115 105
1
2
3
df2 = df.iloc[[1,3],2:4] #取第1、 3行,第2、 3列
df2 = df.loc[['王二姐','李四弟'],'数学':'英语'] #和上一行等价
print(df2)
1
2
3
        数学  英语
王二姐 87 105
李四弟 80 50

DataFrame的分析统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
print("---下面是DataFrame的分析和统计---")
print(df.T) #df.T是df的转置矩阵,即行列互换的矩阵
print(df.sort_values('语文',ascending=False)) #按语文成绩降序排列,不会改变原来的表格,会返回一个新的表格

#print(df.sum()['语文'],df.mean()['数学'],df.median()['英语'])
print(df['语文'].sum(),df['数学'].mean(),df['英语'].median())
#>>435 85.5 101.0 语文分数之和、数学平均分、英语中位数
#df.sum()返回一个Series,每一列的和

print(df.min()['语文'],df.max()['数学'])
#>>100 115 语文最低分,数学最高分

#print(df.max(axis = 1)['王二姐']) #>>115 王二姐的最高分科目的分数
print(df.max(axis = 1, numeric_only=True)['王二姐']) #>>115 王二姐的最高分科目的分数
print(df['语文'].idxmax()) #>>王二姐 语文最高分所在行的标签
print(df['数学'].argmin()) #>>2 数学最低分所在行的行号
print(df.loc[(df['语文'] > 100) & (df['数学'] >= 85)])
1
2
3
sort_values(....inplace=True,axis=1....)
#inplace=True,原地排序,将各列排序,即改变原来的表格
#axis=1,列重新排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
       性别  语文  数学  英语
刘一哥 男 108 115 97
王二姐 女 115 87 105
张三妹 女 100 60 130
李四弟 男 112 80 50
>>上方为原始df
刘一哥 王二姐 张三妹 李四弟
性别 男 女 女 男
语文 108 115 100 112
数学 115 87 60 80
英语 97 105 130 50
性别 语文 数学 英语
王二姐 女 115 87 105
李四弟 男 112 80 50
刘一哥 男 108 115 97
张三妹 女 100 60 130
435 85.5 101.0
100 115
115
王二姐
2
性别 语文 数学 英语
刘一哥 男 108 115 97
王二姐 女 115 87 105

DataFrame的修改和增删

1
2
3
4
5
6
7
8
9
10
print("---下面是DataFrame的增删和修改---")
df.loc['王二姐','英语'] = df.iloc[0,1] = 150 #修改王二姐英语和刘一哥语文成绩
df['物理'] = [80,70,90,100] #为所有人添加物理成绩这一列
df.insert(1,"体育",[89,77,76,45]) #为所有人插入体育成绩到第1列
df.loc['李四弟'] = ['男',100,100,100,100,100] #修改李四弟全部信息
df.loc[:,'语文'] = [20,20,20,20] #修改所有人语文成绩
df.loc['钱五叔'] = ['男',100,100,100,100,100] #加一行
df.loc[:,'英语'] += 10 #>>所有人英语加10分
df.columns = ['性别','体育','语文','数学','English','物理'] #改列标签
print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
>>df初始
性别 语文 数学 英语
刘一哥 男 108 115 97
王二姐 女 115 87 105
张三妹 女 100 60 130
李四弟 男 112 80 50

性别 体育 语文 数学 English 物理
刘一哥 男 89 20 115 107 80
王二姐 女 77 20 87 160 70
张三妹 女 76 20 60 140 90
李四弟 男 100 20 100 110 100
钱五叔 男 100 100 100 110 100
1
2
3
4
5
df.drop(['体育','物理'], axis=1, inplace=True) #删除体育和物理成绩
#inplace=True,代表原数据中删除
df.drop('王二姐', axis = 0, inplace=True) #删除 王二姐那一行
#axis = 0,代表作为行标签删除
print(df)
1
2
3
4
5
       性别  语文  数学  English
刘一哥 男 20 115 107
张三妹 女 20 60 140
李四弟 男 20 100 110
钱五叔 男 100 100 110
1
2
3
df.drop([df.index[i] for i in range(1,3)], axis = 0, inplace = True)
#删除第1,2行
df.drop([df.columns[i] for i in range(3)], axis = 1, inplace = True) #删除第0到2列

数据分析库pandas读写excel和csv文档

用pandas读excel文档

  • 需要openpyxl(对.xlsx文件)或xlrd或xlwt支持(老的.xls文件)
  • 读取的每张工作表都是一个DataFrame
1
2
3
4
5
6
7
8
9
10
import pandas as pd
pd.set_option('display.unicode.east_asian_width',True)
dt = pd.read_excel("excel_sample.xlsx", sheet_name=['销售情况',1], index_col=0)#读取第0和第1张工作表
df = dt['销售情况'] #dt是字典,df是DataFrame
print(df.iloc[0,0], df.loc['睡袋','数量']) #>>4080 4080
print(df)

print(pd.isnull(df.loc['彩盒','销售额'])) #>>True
df.fillna(0,inplace=True) #空的数据值是NaN,将所有NaNa用0替换
print(df.loc['彩盒','销售额'],df.iloc[2,2]) #>>0.0 0.0

用pandas写excel文档

1
df.to_excel(filename,sheet_name="Sheet1",na_rep='',........)
  • 将DataFrame对象df中的数据写入excel文档filename中的”Sheet1”工作表,NaN用’’代替。
  • 会覆盖原有的filename文件
  • 如果要在一个excel文档中写入多个工作表, 需要用ExcelWrite
1
2
3
4
5
6
7
8
9
#(接上面程序)
writer = pd.ExcelWriter("new.xlsx") #创建ExcelWriter对象
df.to_excel(writer,sheet_name="S1")
df.T.to_excel(writer,sheet_name="S2") #转置矩阵写入
df.sort_values('销售额',ascending= False).to_excel(writer, sheet_name="S3")

#按销售额排序的新DataFrame写入工作表S3
df['销售额'].to_excel(writer,sheet_name="S4") #只写入一列
writer.save()

Pandas不可以指定单元格的样式openxl可以

用pandas读写csv文件

1
2
3
df.to_csv("result.csv",sep=",",na_rep='NA',
float_format="%.2f",encoding="gbk")
df = pd.read_csv("result.csv")

用matplotlib进行数据展示

1
pip install matplotlib

绘制直方图

绘制基本直方图

1
2
3
4
5
6
7
8
9
10
11
import matplotlib.pyplot as plt #以后 plt 等价于 matplotlib.pyplot
from matplotlib import rcParams
rcParams['font.family'] = rcParams['font.sans-serif'] = 'SimHei'
#设置中文支持,中文字体为简体黑体
ax = plt.figure().add_subplot() #建图,获取子图对象ax
ax.bar(x = (0.2,0.6,0.8,1.2), height = (1,2,3,0.5), width = 0.1)
#x表示4个柱子中心横坐标分别是0.2,0.6,0.8,1
#height表示4个柱子高度分别是1,2,3,0.5
#width表示柱子宽度0.1
ax.set_title('我的直方图') #设置标题
plt.show() #显示绘图结果

绘制横向直方图

1
2
3
4
#纵向
ax.bar(x = (0.2,0.6,0.8,1.2), height = (1,2,3,0.5), width = 0.1)
#横向
ax.barh(y = (0.2,0.6,0.8,1.2), width = (1,2,3,0.5), height = 0.1)

绘制堆叠直方图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt
ax = plt.figure().add_subplot()
labels = ['Jan', 'Feb', 'Mar', 'Apr']
num1 = [20, 30, 15, 35] #Dept1的数据
num2 = [15, 30, 40, 20] #Dept2的数据
cordx = range(len(num1)) #x轴刻度位置
rects1 = ax.bar(x = cordx, height=num1, width=0.5, color='red', label="Dept1")
rects2 = ax.bar(x = cordx, height=num2, width=0.5, color='green',
label="Dept2", bottom=num1)
ax.set_ylim(0, 100) #y轴坐标范围
ax.set_ylabel("Profit") #y轴含义(标签)
ax.set_xticks(cordx) #设置x轴刻度位置
ax.set_xticklabels(labels) #设置x轴刻度下方文字
ax.set_xlabel("In year 2020") #x轴含义(标签)
ax.set_title("My Company")
ax.legend() #在右上角显示图例说明
plt.show()

绘制对比直方图(有多组数据)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import matplotlib.pyplot as plt
ax = plt.figure(figsize=(10,5)).add_subplot()#建图,获取子图对象ax
ax.set_ylim(0,400) #指定y轴坐标范围
ax.set_xlim(0,80) #指定x轴坐标范围

#以下是3组直方图的数据
x1 = [7, 17, 27, 37, 47, 57] #第一组直方图每个柱子中心点的横坐标
x2 = [13, 23, 33, 43, 53, 63] #第二组直方图每个柱子中心点的横坐标
x3 = [10, 20, 30, 40, 50, 60] #第三组直方图每个柱子中心点的横坐标
y1 = [41, 39, 13, 69, 39, 14] #第一组直方图每个柱子的高度
y2 = [123, 15, 20, 105, 79, 37] #第二组直方图每个柱子的高度
y3 = [124, 91, 204, 264, 221, 175] #第三组直方图每个柱子的高度

rects1 = ax.bar(x1, y1, facecolor='red', width=3, label='Iphone')
rects2 = ax.bar(x2, y2, facecolor='green', width=3, label='Huawei')
rects3 = ax.bar(x3, y3, facecolor='blue', width=3, label='Xiaomi')

ax.set_xticks(x3) #x轴在x3中的各坐标点下面加刻度
ax.set_xticklabels(('A1','A2','A3','A4','A5','A6'))
#指定x轴上每一刻度下方的文字
ax.legend() #显示右上角三组图的说明

def label(ax,rects): #在rects的每个柱子顶端标注数值
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width()/2, height+14, str(height), rotation=90) #文字旋转90度
label(ax,rects1)
label(ax,rects2)
label(ax,rects3)

plt.show()

绘制散点、折线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import math,random
import matplotlib.pyplot as plt
def drawPlot(ax):
xs = [i / 100 for i in range(1500)] #1500个点的横坐标,间隔0.01
ys = [10*math.sin(x) for x in xs]
#对应曲线y=10*sin(x)上的1500个点的y坐标
ax.plot(xs, ys, "red", label="Beijing") #画曲线y=10*sin(x)
ys = list(range(-18, 18))
random.shuffle(ys)
ax.scatter(range(16), ys[:16], c = "blue") #画散点
ax.plot(range(16), ys[:16], "blue", label="Shanghai") #画折线
ax.legend() #显示右上角的各条折线说明
ax.set_xticks(range(16)) #x轴在坐标0,1...15处加刻度
ax.set_xticklabels(range(16)) #指定x轴每个刻度下方显示的文字
ax = plt.figure(figsize=(10, 4),dpi=100).add_subplot() #图像长宽和清晰度
drawPlot(ax)
plt.show()

绘制饼图

1
2
3
4
5
6
7
8
9
10
11
import matplotlib.pyplot as plt
def drawPie(ax):
lbs = ('A', 'B', 'C', 'D') #四个扇区的标签
sectors = [16, 29.55, 44.45, 10] #四个扇区的份额(百分比)
expl = [0, 0.1, 0, 0] #四个扇区的突出程度
ax.pie(x=sectors, labels=lbs, explode=expl, autopct='%.2f', shadow=True, labeldistance=1.1, pctdistance=0.6, startangle=90)
#autopct自动填充数字的格式,shadow是否有阴影,labeldistance扇区标签的距离,pctdistance饼内标签距离圆心距离是半径的多少倍,startangle画图的起始位置逆时针顺序
ax.set_title("pie sample") #饼图标题
ax = plt.figure().add_subplot()
drawPie(ax)
plt.show()

绘制热力图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
from matplotlib import pyplot as plt
data = np.random.randint(0, 100, 30).reshape(5, 6)
#生成一个5行6列,元素[0,100]内的随机矩阵
xlabels = ['Beijing', 'Shanghai', 'Chengdu', 'Guangzhou', 'Hangzhou', 'Wuhan']
ylabels = ['2016', '2017', '2018', '2019', '2020']

ax = plt.figure(figsize=(10,8)).add_subplot()
ax.set_yticks(range(len(ylabels))) #y轴在坐标[0,len(ylabels)) 处加刻度
ax.set_yticklabels(ylabels) #设置y轴刻度文字
ax.set_xticks(range(len(xlabels)))
ax.set_xticklabels(xlabels)

heatMp = ax.imshow(data, cmap=plt.cm.hot, aspect='auto', vmin=0, vmax=100)
#imshow(data矩阵, cmap=plt.cm.cold冷图, aspect, vmin-vmx指明热力图的最大最小值 不写取数据最大最小)

#热力图写数据标签
for i in range(len(xlabels)):
for j in range(len(ylabels)):
ax.text(i, j, data[j][i], ha="center", va="center", color="blue", size=26)

plt.colorbar(heatMp) #绘制右边的颜色-数值对照柱
plt.xticks(rotation=45, ha="right") #将x轴刻度文字进行旋转,且水平方向右对齐
plt.title("Sales Volume(ton)")
plt.show()

绘制雷达图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import matplotlib.pyplot as plt
from matplotlib import rcParams #处理汉字用
def drawRadar(ax):
pi = 3.1415926
labels = ['EQ','IQ','人缘','魅力','财富','体力'] #6个属性的名称
attrNum = len(labels) #attrNum是属性种类数,此处等于6
data = [7,6,8,9,8,2] #六个属性的值
angles = [2*pi*i/attrNum for i in range(attrNum)]
#angles是以弧度为单位的6个属性对应的6条半径线的角度
angles2 = [x * 180/pi for x in angles]
#angles2是以角度为单位的6个属性对应的半径线的角度
ax.set_ylim(0, 10)
#限定半径线上的坐标范围,限定模长
ax.set_thetagrids(angles2, labels, fontproperties="SimHei")
#绘制6个属性对应的6条半径(六条半径角度, 属性, 字体样式)
ax.fill(angles, data, facecolor='g', alpha=0.25)
#填充,facecolor='g'绿色填充,alpha:透明度
rcParams['font.family'] = rcParams['font.sans-serif'] = 'SimHei'
#处理汉字
ax = plt.figure().add_subplot(projection="polar") #生成极坐标形式子图
drawRadar(ax)
plt.show()

绘制多层雷达图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import matplotlib.pyplot as plt
from matplotlib import rcParams

rcParams['font.family'] = rcParams['font.sans-serif'] = 'SimHei'
pi = 3.1415926
labels = ['EQ', 'IQ', '人缘', '魅力', '财富', '体力'] # 6个属性的名称
attrNum = len(labels)
names = ('张三', '李四', '王五')
data = [[0.40, 0.32, 0.35], [0.85, 0.35, 0.30],
[0.40, 0.32, 0.35], [0.40, 0.82, 0.75],
[0.14, 0.12, 0.35], [0.80, 0.92, 0.35]] # 三个人的数据
angles = [2 * pi * i / attrNum for i in range(attrNum)]
angles2 = [x * 180 / pi for x in angles]
ax = plt.figure().add_subplot(projection="polar")
ax.fill(angles, data, alpha=0.25)
ax.set_thetagrids(angles2, labels)
ax.set_title('三巨头人格分析', y=1.05) # y指明标题垂直位置
ax.legend(names, loc=(0.95, 0.9)) # 画出右上角不同人的颜色说明
plt.show()

多子图绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#程序中的import、汉字处理及drawRadar、 drawPie、 drawPlot函数略,见前面程序
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(2, 2, 1) # 窗口分割成2*2,取位于第1个方格的子图
drawPie(ax)

ax = fig.add_subplot(2, 2, 2, projection="polar")
drawRadar(ax)

ax = plt.subplot2grid((2, 2), (1, 0), colspan=2)
# 或写成: ax = fig.add_subplot(2,1,2)
drawPlot(ax)

plt.figtext(0.05, 0.05, 'subplot sample') # 显示左下角的图像标题
plt.show()

词云的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# coding=utf-8
# Version:python3.6.0
# 添加自定义分词

import jieba
from os import path # 用来获取文档的路径

# 词云
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
# 词云生成工具
from wordcloud import WordCloud, ImageColorGenerator
# 需要对中文进行处理
import matplotlib.font_manager as fm

# 背景图
bg = np.array(Image.open("love.png"))

# 获取当前的项目文件加的路径
d = path.dirname(__file__)
# 读取停用词表
stopwords_path = 'stopwords.txt'
# 添加需要自定以的分词
# jieba.add_word("叶文洁")

# 读取要分析的文本
text_path = "sanguoyanyiutf8.txt"
# 读取要分析的文本,读取格式
text = open(path.join(d, text_path), encoding="utf8").read()


# 定义个函数式用于分词
def jiebaclearText(text):
# 定义一个空的列表,将去除的停用词的分词保存
mywordList = []
# 进行分词
seg_list = jieba.cut(text, cut_all=False)
# 将一个generator的内容用/连接
listStr = '/'.join(seg_list)
# 打开停用词表
f_stop = open(stopwords_path, encoding="utf8")
# 读取
try:
f_stop_text = f_stop.read()
finally:
f_stop.close() # 关闭资源
# 将停用词格式化,用\n分开,返回一个列表
f_stop_seg_list = f_stop_text.split("\n")
# 对默认模式分词的进行遍历,去除停用词
for myword in listStr.split('/'):
# 去除停用词
if not (myword.split()) in f_stop_seg_list and len(myword.strip()) > 1:
mywordList.append(myword)
return ' '.join(mywordList)


text1 = jiebaclearText(text)
# 生成
wc = WordCloud(
background_color="white", # 设置背景为白色,默认为黑色
width=990, # 设置图片的宽度
height=440, # 设置图片的高度
margin=10, # 设置图片的边缘

max_font_size=50,
random_state=30,
font_path='C:/Windows/Fonts/simkai.ttf' # 中文处理,用系统自带的字体
).generate(text1)
# 为图片设置字体
my_font = fm.FontProperties(fname='C:/Windows/Fonts/simkai.ttf')
# 产生背景图片,基于彩色图像的颜色生成器
image_colors = ImageColorGenerator(bg)
# 开始画图
plt.imshow(wc)
# 为云图去掉坐标轴
plt.axis("off")
# 画云图,显示
# 保存云图
wc.to_file("sgresult3.png")
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2023/02/01/实用Python程序设计MOOC-第十一章数据分析和展示/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
好用、实惠、稳定的梯子,点击这里