数据可视化是数据科学家工作的重要组成部分。在项目的早期阶段,大家通常会进行探索性数据分析,以便深入了解数据分布。创建可视化确实有助于让事情更清晰、更容易理解,尤其是对于较大的高维数据集。
本文将介绍五种数据可视化技巧,闲话少说,我们直接开始吧!
02
散点图
散点图非常适合显示两个变量之间的关系,因为大家可以直接看到数据的原始分布。此外还可以通过对不同组的数据进行颜色编码来查看它们之间的关系,如下图所示。想要直观显示三个变量之间的关系?没问题!只需使用另一个参数(如点的大小)对第三个变量进行编码,如下图二所示。
带颜色分组的散点图
第三变量用颜色分组和大小编码的散点图
现在开始编写代码。首先,我们首先导入 Matplotlib 的 pyplot。接着我们调用 plt.subplots()创建一个新的图形。我们将 x 轴和 y 轴数据传递给函数,然后将这些数据传递给 ax.scatter(),绘制散点图。我们还可以设置点的大小、点的颜色和 alpha 透明度。甚至还可以将 y 轴设置为对数刻度。然后,标题和坐标轴标签将专门针对该图进行设置。这是一个易于使用的函数,可以方便地创建散点图!
import matplotlib.pyplot as plt
import numpy as np
def scatterplot(x_data, y_data, x_label="", y_label="", title="", color = "r", yscale_log=False):
# Create the plot object
_, ax = plt.subplots()
# Plot the data, set the size(s), color and transparency(alpha)
# of the points
ax.scatter(x_data, y_data, s = 10, color = color, alpha = 0.75)
if yscale_log == True:
ax.set_yscale('log')
# Label the axes and provide a title
ax.set_title(title)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
03
折线图
当大家观察到一个变量与另一个变量之间存在很大差异时,即它们之间存在很大的协方差时,最适合使用折线图进行展示。请看下图。我们可以清楚地看到,随着时间的推移,所有专业的百分比都有很大的变化。如果用散点图来绘制,会非常杂乱无章,很难真正理解和看清发生了什么。折线图非常适合这种情况,因为它基本上可以快速概括两个变量(百分比和时间)的协方差。同样,我们也可以使用颜色编码进行分组。
折线图示例
下面是折线图的代码。它与上面的散点图非常相似,只是变量略有不同。
def lineplot(x_data, y_data, x_label="", y_label="", title=""):
# Create the plot object
_, ax = plt.subplots()
# Plot the best fit line, set the linewidth(lw), color and
# transparency(alpha)of the line
ax.plot(x_data, y_data, lw = 2, color = '#539caf', alpha = 1)
# Label the axes and provide a title
ax.set_title(title)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
04
直方图
直方图对于查看或发现数据点的分布非常有用。请看下面的直方图,我们绘制了频率与智商的直方图。我们可以清楚地看到数据向中心集中,以及中位数是多少。我们还可以看到它遵循高斯分布。使用条形图(而不是散点图)可以让我们清楚地看到每个分区频率之间的相对差异。使用二进制(离散化)确实有助于我们看到 "更大的画面",而如果我们使用所有的数据点而不使用离散二进制,可视化效果中可能会有很多噪音,从而难以看到真正发生了什么。
直方图示例
Matplotlib 中绘制直方图代码如下所示。有两个参数需要注意。首先,n_bins 参数控制直方图的离散分区数量。更多的分区可以提供更精细的信息,但也可能会引入噪音,使我们偏离大局;另一方面,更少的分区可以提供更 "鸟瞰 "的视野,让我们更清楚地看到发生了什么,而不需要更精细的细节。其次,累积参数是一个布尔值,允许我们选择直方图是否累积。这基本上是选择概率密度函数(PDF)或累积密度函数(CDF)。
def histogram(data, n_bins, cumulative=False, x_label = "", y_label = "", title = ""):
_, ax = plt.subplots()
ax.hist(data, n_bins = n_bins, cumulative = cumulative, color = '#539caf')
ax.set_ylabel(y_label)
ax.set_xlabel(x_label)
ax.set_title(title)
想象一下,有时我们要比较数据中两个变量的分布情况。有人可能会认为,你必须分别制作两个直方图,然后将它们并排放在一起进行比较。但是,实际上有一个更好的方法:我们可以用不同的透明度叠加直方图。请看下图。均匀分布的透明度设置为 0.5,这样我们就能看到它后面的内容。这样我们就可以在同一张图上直接查看两种分布。
叠加直方图
在代码中需要对重叠直方图进行一些设置。首先,我们要设置水平范围,以适应两个变量的分布。根据这个范围和所需的分隔数,我们可以实际计算每个分隔的宽度。最后,我们将两个直方图绘制在同一幅图上,其中一个直方图的透明度略高一些。
# Overlay 2 histograms to compare them
def overlaid_histogram(data1, data2, n_bins = 0, data1_name="", data1_color="#539caf", data2_name="", data2_color="#7663b0", x_label="", y_label="", title=""):
# Set the bounds for the bins so that the two distributions are fairly compared
max_nbins = 10
data_range = [min(min(data1), min(data2)), max(max(data1), max(data2))]
binwidth =(data_range[1] - data_range[0])/ max_nbins
if n_bins == 0
bins = np.arange(data_range[0], data_range[1] + binwidth, binwidth)
else:
bins = n_bins
# Create the plot
_, ax = plt.subplots()
ax.hist(data1, bins = bins, color = data1_color, alpha = 1, label = data1_name)
ax.hist(data2, bins = bins, color = data2_color, alpha = 0.75, label = data2_name)
ax.set_ylabel(y_label)
ax.set_xlabel(x_label)
ax.set_title(title)
ax.legend(loc = 'best')
05
条形图
条形图在可视化类别较少(可能小于 10 个)的分类数据时最为有效。如果类别太多,条形图就会显得非常杂乱,难以理解。条形图很适合分类数据,因为您可以根据条形图的大小(即幅度)很容易地看出类别之间的差异;类别也很容易划分和用颜色编码。我们将看到三种不同类型的条形图:常规条形图、分组条形图和堆叠条形图。边看数据边查看下面的代码。
常规条形图如下图所示。在 barplot()函数中,x_data 表示 x 轴上的股票代码,y_data 表示 y 轴上的条形图高度。误差条是以每个条形图为中心的附加线,可以用来显示标准偏差。
常规条形图
代码如下:
def barplot(x_data, y_data, error_data, x_label="", y_label="", title=""):
_, ax = plt.subplots()
# Draw bars, position them in the center of the tick mark on the x-axis
ax.bar(x_data, y_data, color = '#539caf', align = 'center')
# Draw error bars to show standard deviation, set ls to 'none'
# to remove line between points
ax.errorbar(x_data, y_data, yerr = error_data, color = '#297083', ls = 'none', lw = 2, capthick = 2)
ax.set_ylabel(y_label)
ax.set_xlabel(x_label)
ax.set_title(title)
分组条形图允许我们比较多个分类变量。请看下面的条形图。我们要比较的第一个变量是各组(G1、G2......等组)的分数差异。我们还用颜色代码来比较性别本身。看一下代码,y_data_list 变量现在实际上是一个列表,其中每个子列表代表一个不同的组。然后,我们循环查看每个组别,并为每个组别在 x 轴上的每个刻度线绘制条形图;每个组别也用颜色代码表示。
分组条形图
代码如下:
def groupedbarplot(x_data, y_data_list, colors, y_data_names="", x_label="", y_label="", title=""):
_, ax = plt.subplots()
# Total width for all bars at one x location
total_width = 0.8
# Width of each individual bar
ind_width = total_width / len(y_data_list)
# This centers each cluster of bars about the x tick mark
alteration = np.arange(-(total_width/2), total_width/2, ind_width)
# Draw bars, one category at a time
for i in range(0, len(y_data_list)):
# Move the bar to the right on the x-axis so it doesn't
# overlap with previously drawn ones
ax.bar(x_data + alteration[i], y_data_list[i], color = colors[i], label = y_data_names[i], width = ind_width)
ax.set_ylabel(y_label)
ax.set_xlabel(x_label)
ax.set_title(title)
ax.legend(loc = 'upper right')
堆叠条形图是可视化不同变量分类构成的绝佳工具。在下面的堆叠条形图中,我们比较了每天的服务器负载。通过彩色编码的堆叠条形图,我们可以很容易地看到并了解哪些服务器每天工作最多,以及这些服务器的负载与其他服务器的负载相比如何。其代码与分组条形图的风格相同。我们在每个组中循环,只不过这次是在旧条形图的顶部而不是旁边绘制新条形图。
堆叠条形图
代码如下:
def stackedbarplot(x_data, y_data_list, colors, y_data_names="", x_label="", y_label="", title=""):
_, ax = plt.subplots()
# Draw bars, one category at a time
for i in range(0, len(y_data_list)):
if i == 0:
ax.bar(x_data, y_data_list[i], color = colors[i], align = 'center', label = y_data_names[i])
else:
# For each category after the first, the bottom of the
# bar will be the top of the last category
ax.bar(x_data, y_data_list[i], color = colors[i], bottom = y_data_list[i - 1], align = 'center', label = y_data_names[i])
ax.set_ylabel(y_label)
ax.set_xlabel(x_label)
ax.set_title(title)
ax.legend(loc = 'upper right')
06
箱形图
我们之前看过直方图,它非常适合直观显示变量的分布情况。但如果我们需要更多信息呢?也许我们想要更清楚地了解标准偏差?也许中位数与平均值相差很大,因此我们有很多离群值?如果存在偏斜,许多值都集中在一边呢?
这就是方框图的作用。方框图提供了上述所有信息。实线方框的底部和顶部总是第一四分位数和第三四分位数(即 25% 和 75% 的数据),方框内的带状区域总是第二四分位数(中位数)。末端带有条纹的虚线从方框中延伸出来,显示数据的范围。
箱形图示例
由于箱形图是针对每个组/变量绘制的,因此设置起来非常简单。x_data 是一个组/变量列表。Matplotlib 函数 boxplot()为 y_data 的每一列或 y_data 序列中的每个向量绘制盒状图;因此 x_data 中的每个值都对应 y_data 中的一列/向量。我们需要设置的只是绘图的美观度。
代码如下:
def boxplot(x_data, y_data, base_color="#539caf", median_color="#297083", x_label="", y_label="", title=""):
_, ax = plt.subplots()
# Draw boxplots, specifying desired style
ax.boxplot(y_data
# patch_artist must be True to control box fill
, patch_artist = True
# Properties of median line
, medianprops = {'color':median_color}
# Properties of box
, boxprops = {'color':base_color, 'facecolor':base_color}
# Properties of whiskers
, whiskerprops = {'color':base_color}
# Properties of whisker caps
, capprops = {'color':base_color})
# By default, the tick label starts at 1 and increments by 1 for
# each box drawn. This sets the labels to the ones we want
ax.set_xticklabels(x_data)
ax.set_ylabel(y_label)
ax.set_xlabel(x_label)
ax.set_title(title)
07
总结
这就是使用 Matplotlib 进行的 5 种快速而简单的数据可视化技巧。将事物抽象为函数总是能让你的代码更易于阅读和使用!希望你喜欢这篇文章,并能学到有用的新知识。