Python 基于 Matplotlib 实现数据可视化(一)+
4、柱状图
4.1 普通柱状图
柱状图,能够让我们更清晰地查看类别的特征。可以通过 bar(x, height) 函数来绘制柱状图,其中 x 代表的是 x 轴的位置序列,height 代表的是 y 轴的数值序列。
比如,我们从本地读取一份学生成绩的 excel 数据,然后将其用柱状图的方式绘制出来。
在 Excel 中,我们有一份简单的数据,如图所示:
具体代码如下:
import pandas as pd import matplotlib.pyplot as plt users = pd.read_excel('../../user.xlsx') # sort_values 排序,inplace 原地修改,ascending False 从大到小 users.sort_values(by='score', inplace=True, ascending=False) # 直接使用 plt.bar() 绘制柱状图 plt.bar(users.name, users.score, color='orange') # 设置标题、x 轴名称与 y 轴名称,fontsize 设置字号 plt.title('Student Score', fontsize=16) plt.xlabel('Name') plt.ylabel('Score') # 如果 x 轴字体太长,利用 rotation 将其旋转 90 度,方便显示 # plt.xticks(users.name, rotation='90') # 紧凑型布局(因为 x 轴文字较长,为了让其显示全,使用紧凑型布局) plt.tight_layout() plt.show()
运行结果,如图所示:
如果你想要把 X 轴和 Y 轴名称改成中文的,通过添加中文支持就可以了。
import pandas as pd import matplotlib.pyplot as plt users = pd.read_excel('../../user.xlsx') # sort_values 排序,inplace 原地修改,ascending False 从大到小 users.sort_values(by='score', inplace=True, ascending=False) # 直接使用 plt.bar() 绘制柱状图 plt.bar(users.name, users.score, color='orange') # 添加中文字体支持 from matplotlib.font_manager import FontProperties # SimSun.ttc 简体字 font = FontProperties(frame="SimSun.ttc", size=16) # 设置标题、x 轴名称与 y 轴名称,fontsize 设置字号 plt.title('学生分数', fontproper=font) plt.xlabel('名字', fontproperties=font, fontsize=14) plt.ylabel('分数', fontproperties=font, fontsize=14) # 因为 x 轴字体太长,利用 rotation 将其旋转 90 度,方便显示 plt.xticks(users.name, rotation='90') # 紧凑型布局(因为 x 轴文字较长,为了让其显示全,使用紧凑型布局) plt.tight_layout() plt.show()
4.2 叠加柱状图
假设,咱学生的三科考试成绩都出来了,包括语文、数学、英语,那咱想叠加展示的话,就直接使用 stacked 来实现叠加形式。
一样,我们也是需要先去读取 Excel 中的数据,再去绘制。
具体代码如下:
import pandas as pd import matplotlib.pyplot as plt users = pd.read_excel('../../user2.xlsx') # 新计算出一个总量,用于排序 users['Total'] = users['chinese'] + users['english'] + users['math'] # sort_values 排序,inplace 原地修改 users.sort_values(by='Total', inplace=True) # 直接使用 plt.bar() 绘制柱状图 # plt.bar(users.name, users.score, color='orange') # 水平的叠加柱状图,barh 中而 h 表示 horizontal 水平的 # 利用 stacked 就可以实现叠加形式 # users.plot.bar(x='name', y=['chinese', 'english', 'math'], stacked=True) users.plot.barh(x='name', y=['chinese', 'english', 'math'], stacked=True) # 紧凑型布局(因为 x 轴文字较长,为了让其显示全,使用紧凑型布局) plt.tight_layout() plt.show()
运行结果,如图所示:
(1)垂直方向的效果:
(2)水平方向的效果:
5、散点图
散点图描述的是 两个变量之间的关系,将两个变量的值展示在一个二维坐标系中,它跟折线图有点儿相似,区别是散点图只描述数据点,不会将他们练成一根线。
我们可以指定一个范围,通过随机数来绘制一张散点图,感受一下。
非常简单的,具体代码如下:
import matplotlib.pyplot as plt import numpy as np import pandas as pd # 准备数据(此处使用随机数据) N = 1000 x = np.random.randn(N) y = np.random.randn(N) # x:指定 X 轴数据 # y:指定 Y 轴数据 # market:指定散点的图形样式 plt.scatter(x, y, marker='*') # 绘制散点图 plt.show()
运行结果,如图所示:
其中,我们绘制散点图时,用到了 scatter() 函数,除了上面我们用过的参数以外,还有好几个也是比较常见的,下面统一再说明一下:
- x:指定 X 轴数据;
- y:指定 Y 轴数据;
- s:指定散点的大小;
- c:指定散点的颜色;
- alpha:指定散点的透明度;
- linewidths:指定散点边框的粗细;
- edgecolors:指定散点边框的颜色;
- marker:指定散点的图形样式(有很多)
标记 | 说明 | 标记 | 说明 |
. | 点 | s | 正方形 |
, | 像素 | p | 五边形 |
o | 圆形 | * | 星型 |
v | 向下三角 | h | 八边形 |
^ | 向上三角 | H | 八边形2 |
< | 向左三角 | + | 加号 |
> | 向右三角 | x | 乘号 |
1 | 向下三叉 | D | 菱形 |
2 | 向上三叉 | d | 小菱形 |
3 | 向左三叉 | | | 竖线 |
4 | 向右三叉 | _ | 横线 |
- camp:指定散点颜色的映射。
6、直方图
直方图,也叫质量分布图,它主要由一系列高度不等的纵向条纹或线段来表示数据分布的情况。其中,横轴用来表示数据类型,纵轴用来表示分布情况。
在横坐标上,等分成了一定数量的小区间,每个小区间用高矮不一的矩形条来展示区间中的 y 值,此时我们即可观察到数据集的直方图分布的情况。
具体代码如下:
import numpy as np import pandas as pd import matplotlib.pyplot as plt # 准备数据 a = np.random.randn(100) s = pd.Series(a) # 绘制直方图 plt.hist(s) plt.show()
运行结果,如图所示:
7、箱线图
箱线图,可以用来分析数据的差异性、离散程度、异常值等。它由五个部分组成,分别是最大值 (max)、最小值 (min)、中位数 (median) 和上下四分位数 (Q3, Q1)。
通过使用 boxplot(x, labels=None) 函数即可实现,其中,x 指的是要绘制箱线图的数据,labels 用来设置箱线图的标签。
具体代码如下:
import numpy as np import pandas as pd import matplotlib.pyplot as plt # 准备数据 data = np.random.normal(size=(10,5)) lables = ['A','B','C','D','E'] # 用Matplotlib画箱线图 plt.boxplot(data,labels=lables) plt.show()
运行结果,如图所示:
8、雷达图
这是我做了一个项目管理能力的评估效果图,所呈现的图示叫雷达图,也叫蜘蛛图。
它是一种显示一对多关系的方式。在图中,我们可以观察到一个变量相对于另一个变量的显著性是很清晰的。
在设置数据的时候,我们需要指定对应标签的统计数据,也就是 labels 和 stats。
另外,它本质上是一个圆形,需要我们根据标签的个数,来计算出其坐标的角度,再去设置对应的值。
具体代码如下:
![雷达图](../%E9%9B%B7%E8%BE%BE%E5%9B%BE.png)import numpy as np import matplotlib.pyplot as plt # import seaborn as sns # from matplotlib.font_manager import FontProperties # 准备数据 # 语文,数学,英语,物理,化学,体育 labels = np.array(["Chinese","Math","English","Pysics","Cemistry","Sport"]) # 统计值 stats = [85, 60, 90, 77, 86, 85] # 画图数据准备,角度、状态值 # 根据数据长度平均分割圆周长 angles = np.linspace(0, 2*np.pi, len(labels), endpoint=False) # 闭合 stats = np.concatenate((stats,[stats[0]])) angles = np.concatenate((angles,[angles[0]])) labels=np.concatenate((labels,[labels[0]])) # 绘制雷达图 fig = plt.figure() # 将图分成 1 行 1 列,画出位置 1 的图 ax = fig.add_subplot(111, polar=True) ax.plot(angles, stats, 'o-', color='r', linewidth=2) ax.fill(angles, stats, facecolor='r', alpha=0.25) # 设置中文字体 # font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14) # ax.set_thetagrids(angles * 180/np.pi, labels, FontProperties=font) ax.set_thetagrids(angles * 180/np.pi, labels) plt.show()
运行结果,如图所示:
9、等高线图
先看下面这张图,它是「等高线地图」,是一种利用已有的数据,画出地理位置分布图的方式。
等高线地图,就是将地表高度相同的点,连成一环线,直接投影到平面形成水平曲线。不同高度的环线不会相合,除非地表显示悬崖或峭壁,才能使某处线条太密集,而出现重叠现象。若地表出现平坦开阔的山坡,曲线间之距离就相当宽。
在我们数据分析中,我们除了地理数据以外,还有很多其他数据也要做「等高线图」展示,它需要的是三维数据,其中 X、Y 轴数据用来确定坐标点,Z 轴数据则是不同坐标点所对应的高度。
当拿到所有数据之后,可以使用 contour() 函数来进行绘制,如果你想要填充颜色的话,可以使用 contourf() 函数来实现。
常用的参数有:
- X:用于指定 X 轴数据;
- Y:用于指定 Y 轴数据;
- Z:用于指定 X、Y 轴坐标的所对应的高度数据;
- colors:用于指定不同高度的等高线的颜色;
- alpha:用于指定等高线的透明度;
- cmap:用于指定等高线的颜色映射;
- linewidths:用于指定等高线的宽度;
- linesytles:用于指定等高线的样式。
那我们就来画一张吧,很简单的,具体代码如下:
import numpy as np import matplotlib.pyplot as plt # 指定 X,Y 轴数据 # 从左边取值为从 -6 到 6 # 各取 5 个点,一共取 5*5 = 25 个点 x = np.linspace(-3, 3, 5) y = np.linspace(-3, 3, 5) # 将 X,Y 数据进行网格化 X, Y = np.meshgrid(x, y) # 定义等高线高度函数 def f(x, y): return x * (y * 0.2) # 填充颜色 plt.contourf(X, Y, f(X,Y), 10, alpha = 0.75, cmap = 'rainbow') # 绘制等高线 con = plt.contour(X, Y, f(X,Y), 10, colors = 'black', linewidth = 0.5) # 显示各等高线的数据标签 plt.clabel(con, inline = True, fontsize = 10) # 去除坐标轴 plt.xticks(()) plt.yticks(()) plt.show()
运行结果,如图所示:
10、3D 图
画 3D 图,是很好玩儿的,它需要的数据跟上面的等高线图基本一样,先通过 X、Y 轴来指定坐标点,然后再通过 Z 轴来指定坐标点的对应高度。
我们可以使用 Matplotlib 的 scatter3D() 方法来实现;也可以使用 Axes3D 对象的 plot_surface() 方法来实现,我们都拿来玩一下。
先来看看 Matplotlib 的 scatter3D() 方法,具体代码如下:
from matplotlib import pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np ax = plt.axes(projection='3d') # 指定 X、Y、Z 三个坐标轴 zd = 10 * np.random.random(100) xd = 3 * np.sin(zd) yd = 4 * np.cos(zd) # 绘制散点图 # 基本上是 matplotlib 画图的属性设置 ax.scatter3D(xd, yd, zd, c = 'red') plt.show()
运行结果,如图所示:
再来看看 Axes3D 对象的 plot_surface() 方法,具体代码如下:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize = (10, 8)) ax = Axes3D(fig) # 获取 X、Y 数据 x = np.arange(-8,8,0.25) y = np.arange(-8,8,0.25) x,y = np.meshgrid(x,y) r = np.sqrt(x**2 + y**2) # 获取 Z 数据 z = np.sin(r)/2 # 调用 plot_surface() 函数进行绘制 ax.plot_surface(x, y, z, rstride = 1, cstride = 1, cmap = plt.get_cmap('rainbow')) ax.contourf(x, y, z, zdir = 'z', offset = -2) plt.show()
运行结果,如图所示: