数据可视化Matplotlib库

数据可视化是数据科学家工具箱中的一个重要部分。创建可视化很容易,但创建优秀的可视化却很难。

数据可视化有两种主要用途:

  • 探索数据
  • 交流数据

1 matplotlib

有许多工具可以用来可视化数据,我们将使用的是应用最广的 matplotlib 库(尽管这暴露了它的年龄。详见 http://matplotlib.org/)。如果你的兴趣是制作用于网络的精良的交互可视化,它可能不是好的选择,但对于条形图、线图和散点图这些简单的图形来说,它很好用。

特别地,我们会使用 matplotlib.pyplot 模块。在最简单的应用中,pyplot 保持着一种内部状态,你可以在其中一步步地创建可视化。一旦创建工作完成,就可以保存(用 savefig())或显示(用 show())你的图形。

例如,制作一个非常简单的图形,就可以采取以下步骤:

from matplotlib import pyplot as plt

years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10289.7, 14958.3]

# 创建一幅线图,x轴是年份,y轴是gdp
plt.plot(years, gdp, color='green', marker='o', linestyle='solid')

# 添加一个标题
plt.title("名义GDP")

# 给y轴加标记
plt.ylabel("十亿美元")
plt.show()

在这里插入图片描述

图 :一个简单的线图

制作出版级别的精良图片要更加复杂。对图形进行自定义的方式有多种,如坐标轴标记、线型以及点的形状等。我们并不会面面俱到地讲解这些参数,只会在我们的例子中提到(并关注)其中的一些。

2 条形图

如果你想展示某些离散的项目集合中的数量是如何变化的,可以使用条形图。比如,图 显示了几部电影所获得的奥斯卡金像奖的数目:

movies = ["Annie Hall", "Ben-Hur", "Casablanca", "Gandhi", "West Side Story"]
num_oscars = [5, 11, 3, 8, 10]

# 条形的默认宽度是0.8,因此我们对左侧坐标加上0.1
# 这样每个条形就被放置在中心了
xs = [i + 0.1 for i, _ in enumerate(movies)]

# 使用左侧x坐标[xs]和高度[num_oscars]画条形图
plt.bar(xs, num_oscars)

plt.ylabel("所获奥斯卡金像奖数量")
plt.title("我最喜爱的电影")

# 使用电影的名字标记x轴,位置在x轴上条形的中心
plt.xticks([i + 0.5 for i, _ in enumerate(movies)], movies)

plt.show()

在这里插入图片描述

图 :一个简单的条形图

条形图也可以用来绘制拥有大量数值取值的变量直方图,以此来探索这些取值是如何分布的,如图 3-3 所示。

grades = [83,95,91,87,70,0,85,82,100,67,73,77,0]
decile = lambda grade: grade // 10 * 10
histogram = Counter(decile(grade) for grade in grades)

plt.bar([x - 4 for x in histogram.keys()], # 每个条形向左侧移动4个单位
        histogram.values(),                # 给每个条形设置正确的高度
        8)                                 # 每个条形的宽度设置为8

plt.axis([-5, 105, 0, 5])                  # x轴取值从-5到105
                                           # y轴取值0到5

plt.xticks([10 * i for i in range(11)])    # x轴标记为0,10,...,100
plt.xlabel("十分相")
plt.ylabel("学生数")
plt.title("考试分数分布图")
plt.show()

在这里插入图片描述

图:为直方图使用条形图

plt.bar 的第三个参数指定了条形的宽度,在这里我们选择宽度为 8(这样就在各个条形之间留出了小的间隔,因为 x 轴是以刻度 10 做标记的),而且把每个条形向左移了 4 个宽度。这样一来,(比如说)“80”这个条形的左边在 76,而右边在 84,因此它的中心在 80。

对 plt.axis 的调用表明我们希望 x 轴的范围是 -5~105(以使“0”到“100”这些条形可以完全显示),并且 y 轴的范围应限定在 0~5 之间。对 plt.xticks 的调用把 x 轴的刻度放在 0、10、20、……、100 这些位置。

在使用 plt.axis() 时要谨慎。在创建条形图时,y 轴不从 0 开始是一种特别不好的形式,因为这很容易误导人:

mentions = [500, 505]
years = [2013, 2014]

plt.bar([2012.6, 2013.6], mentions, 0.8)
plt.xticks(years)
plt.ylabel("听到有人提及‘数据科学’的次数")

# 如果不这么做,matplotlib会把x轴的刻度标记为0和1
# 然后会在角上加上+2.013e3(糟糕的matplotlib操作!)
plt.ticklabel_format(useOffset=False)

# 这会误导y轴只显示500以上的部分
plt.axis([2012.5,2014.5,499,506])
plt.title("快看如此'巨大'的增长!")
plt.show()

在这里插入图片描述

图 :一个有误导性 y 轴的条形图

在图 中,我们使用了一种更合理的轴,这样它看起来就不那么异常了:

plt.axis([2012.5,2014.5,0,550])
plt.title("增长不那么巨大了")
plt.show()

在这里插入图片描述

图 :y 轴正常的同一个条形图

3 线图

前面提过,可以用 plt.plot() 来制作线图。这种图形可以用来清晰地显示某种事物的趋势,如图 3-6 所示:

variance     = [1, 2, 4, 8, 16, 32, 64, 128, 256]
bias_squared = [256, 128, 64, 32, 16, 8, 4, 2, 1]
total_error  = [x + y for x, y in zip(variance, bias_squared)]
xs = [i for i, _ in enumerate(variance)]

# 可以多次调用plt.plot
# 以便在同一个图上显示多个序列
plt.plot(xs, variance,     'g-',  label='variance')     # 绿色实线
plt.plot(xs, bias_squared, 'r-.', label='bias^2')       # 红色点虚线
plt.plot(xs, total_error,  'b:',  label='total error')  # 蓝色点线

# 因为已经对每个序列都指派了标记
# 所以可以自由地布置图例
# loc=9指的是“顶部中央”
plt.legend(loc=9)
plt.xlabel("模型复杂度")
plt.title("偏差-方差权衡图")
plt.show()

在这里插入图片描述

图 :带有图例的几个线图

4 散点图

散点图是显示成对数据集的可视化关系的好选择。比如,图显示了你的用户们已有的朋友数和他们每天花在网站上的分钟数之间的关系:

friends = [ 70,  65,  72,  63,  71,  64,  60,  64,  67]
minutes = [175, 170, 205, 120, 220, 130, 105, 145, 190]
labels =  ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

plt.scatter(friends, minutes)

# 每个点加标记
for label, friend_count, minute_count in zip(labels, friends, minutes):
    plt.annotate(label,
        xy=(friend_count, minute_count), # 把标记放在对应的点上
        xytext=(5, -5),                  # 但要有轻微偏离
        textcoords='offset points')

plt.title("日分钟数与朋友数")
plt.xlabel("朋友数")
plt.ylabel("花在网站上的日分钟数")
plt.show()

在这里插入图片描述

图 :朋友数与花在网站上的分钟数之间的关系散点图

当你分散了可比较的变量,如果让 matplotlib 选择刻度,可能会得到一个误导性的图,如图所示:

test_1_grades = [ 99, 90, 85, 97, 80]
test_2_grades = [100, 85, 60, 90, 70]

plt.scatter(test_1_grades, test_2_grades)
plt.title("Axes Aren't Comparable")
plt.xlabel("测验1的分数")
plt.ylabel("测验2的分数")
plt.show()

在这里插入图片描述

图 :带有无法比较的轴的散点图

如果我们引入对 plt.axis(“equal”)的调用,图形(图 3-9)会更精确地显示大多数变化是发生在测验 2 上的。

在这里插入图片描述

图 :带有可比较的轴的同一个散点图

5 延伸学习

seaborn(http://web.stanford.edu/~mwaskom/software/seaborn/)基于 matplotlib 构建,让 你可以轻松地制作更漂亮也更复杂的可视化。

D3.js(http://d3js.org/)是一个 JavaScript 库,可以制作精致的基于网络的交互可视化。尽管它并不存在于 Python 中,但它很时髦,并且应用广泛,值得你花时间来了解它。

Bokeh(http://bokeh.pydata.org/en/latest/)是一个较新的库,它将 D3 风格的可视化引入了 Python 中。

ggplot(https://pypi.python.org/pypi/ggplot)是流行的 R 库 ggplot2 的 Python 接口。ggplot2 被广泛用于生成“出版级别”的图形图像。如果你是一个热情的 ggplot2 用户,它可能是非常有趣的工具,但如果你不熟悉它,可能会觉得使用起来有些困难。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值