:::: MENU ::::

TalkingData's Blog

现在开始,用数据说话。

锐眼洞察 | 手把手教你简单快速实现5种数据可视化

  • Mar 19 / 2018
  • 0
Data, Ideas

锐眼洞察 | 手把手教你简单快速实现5种数据可视化

作者:George Seif

原文:https://towardsdatascience.com/5-quick-and-easy-data-visualizations-in-python-with-code-a2284bae952f

译者:TalkingData数据工程师 新壮

本译文禁止商用,转载请注明来源!

数据可视化是数据科学家工作中的一个重要部分。在项目的早期阶段,你通常会进行探索性数据分析(EDA),以获得对数据的一些见解。创建可视化确实有助于使数据更易懂,特别是对于更大的高维数据集。在你的项目即将结束时,重要的是能够以清晰、简明和令人信服的方式展示你的最终结果,让你的听众可以理解,而他们通常是不懂技术的客户。

Matplotlib是一种流行的Python库,可以非常容易地用来创建数据可视化。然而,每次创建一个新项目时,设置数据、参数、图形和绘图都会非常混乱和乏味。在这篇博客中,我们会使用Matplotlib库写一些快速且简单的函数,实现5种图形可视化。同时,这里有一个非常好的图表,可以为你在工作中选择合适的可视化提供参考!

根据不同情况选择合适的数据可视化技术

散点图 

散点图很好地显示了两个变量之间的关系,因为你可以直接看到数据的原始分布。您也可以通过颜色编码来查看不同组数据之间的关系,如下图所示。想可视化三个变量之间的关系吗?没问题!只需使用另一个参数,比如点大小,对第三个变量进行编码就可以,如下面的第二个图所示。

颜色分组散点图

按颜色分组并对三个变量进行了大小编码的散点图

现在该展示代码了。我们首先引入Matplotlib的pyplot并命名为“plt”。通过调用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)

线形图 

当你想清楚展示一个变量随另一个变量明显变化时(例如它们有很高的协方差),最好使用线形图。让我们通过下图来说明。

我们可以清楚地看到,所有专业的百分比随着时间的推移有很大的变化。用散点图来绘制这些图形会非常混乱,很难真正理解并看出正在发生的事情。对这种情况来说,线形图则是完美的,因为它们基本上快速地给我们总结了这两个变量的协方差(百分比和时间)。同样,我们还可以使用颜色编码对其分组。

线形图示例

下面是线形图的代码。它和上面的散点图很相似,只是变量有一些细微的变化。

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)
view raw

直方图 

直方图对于显示或发现数据点的分布非常有用。看看下面的直方图,我们画出频率 vs IQ直方图。我们可以清楚地看到均值和中位数是什么。我们也可以看到它遵循高斯分布。使用直方图(而不是散点图)可以让我们清楚地看到每个bin(直方)频率之间的相对差异。使用bin(经过离散化)确实帮助我们看到“更大的图景”,因为如果我们使用所有的数据点而不是离散化后的bin,那么在可视化中可能会有很多噪音,很难看清到底发生了什么。

直方图实例

使用Matplotlib绘制直方图的代码如下所示。有两个参数需要注意。首先,n_bins参数控制我们希望我们的直方图有多少个离散箱。更多的bins会给我们提供更详细的信息,但也可能会带来噪音,使我们远离更大的画面;另一方面,减少bins给我们更多的“鸟瞰”,描述发生了什么事情而没有更详细的细节。其次,cumulative参数是一个布尔值,它允许我们选择我们的直方图是否累积。也就是说选择的是概率密度函数(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')

柱状图 

当你试图把类别较少(大概是10个)的分类数据可视化时,柱状图最有效。如果我们有太多的类别,那么柱状图将是非常混乱,并且难以理解。它们对于分类数据是很好的,因为你可以很容易地根据柱状的形状(例如大小)来区分类别之间的区别;类别也很容易划分和进行颜色编码。我们要看3种不同类型的柱状图:常规的、分组的和堆积的。下图中代码的顺序与图的顺序一致。

常规柱状图是下面的第一个图。在barplot()函数中,x_data代表X轴上的tickers和y_data代表Y轴上的柱状高度。error线是一条在每一柱状中间的额外的线,可以画出以显示标准差。

常规柱状图

分组柱状图允许我们比较多个分类变量。看看下面的第二个柱状图。我们首先比较的变量是分数如何根据组(G1,G2等)而变化。我们还通过颜色编码比较了他们的性别。我们来看一看代码,y_data_list变量现在真的是一个列表的列表,其中每个子列表代表一个不同的组。然后我们遍历每个组,对于每个组绘制x轴上的每一个刻度条,每组也是颜色编码的。

分组柱状图

堆积柱状图非常适合可视化不同变量的类别构成。在下面的堆积柱状图中,我们一天天地比较服务器负载。通过颜色编码后的堆,我们可以很容易地看到并理解哪一台服务器每天工作最多,以及一台服务器负载如何与其他服务器进行比较。此代码遵循与分组柱状图相同的样式。除了我们遍历每个组时在旧的上面画新的条,而不是在它们旁边。

堆积柱状图

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)

   
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')

   
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')

箱线图 

我们以前研究过直方图,其对于可视化变量的分布非常有用。但是如果我们需要更多的信息呢?也许我们想更清楚地看一下标准差?也许中位数与平均值有很大的不同,因此我们有很多离群值。如果数据有倾斜,许多值集中在一边呢?

那就是箱线图发挥作用的时候了。箱线图给了我们上面所有的信息实线盒的底部和顶部总是第一和第三分位(即数据的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)

结论 

以上就是使用Matplotlib简单快速实现的5种数据可视化。把事情抽象成函数总能让代码更易于阅读和使用。希望你喜欢这篇文章,并学到一些新的、有用的东西。如果你没有,就随便给它一些掌声吧~

Leave a comment

随时欢迎您 联系我们