Python数据可视化

第一章生成数据

数据可视化 指的是通过可视化表示来探索数据。它与数据分析 紧密相关,而数据分析指的是使用代码来探索数据集的规律和关联。数据集可 以是用一行代码就能表示的小型数字列表,也可以是数千兆字节的数据。

1.1安装Matplotlib

    本章将首先使用Matplotlib来生成几个图表,为此需要使用 pip 来安装它。 pip 是 一个可用于下载并安装Python包的模块。请在终端提示符下执行如下命令:

python -m pip install --user matplotlib

在你的系统中,如果运行程序或启动终端会话时使用的命令不是 python , 而是python3 ,应使用类似于下面的命令:

python3 -m pip install --user matplotlib

1.2 绘制简单的折线图

下面使用Matplotlib绘制一个简单的折线图,再对其进行定制,以实现信息更丰富 的数据可视化效果。我们将使用平方数序列1、4、9、16和25来绘制这个图表。只需提供如下的数,Matplotlib将完成其他工作:

import matplotlib.pyplot as plt
squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(squares)
plt.show()

①  首先导入模块pyplot ,并为其指定别名 plt ,以免反复输入 pyplot。
 ②  我们创建了一个名为squares 的列表,在其中存储要用来制作图表的数据。
 ③ 调用函数subplots(),这个函数可在一张图片中绘制一个或多个图表。变量fig 表示整张图片。变 量ax 表示图片中的各个图表,大多数情况下要使用它。
 ④方法plot() ,它尝试根据给定的数据以有意义的方式绘制图表。
 ⑤ 函数 plt.show() 打开Matplotlib查看器并显示绘制的图表


1.2.1 修改标签文字和线条粗细

图形表明数是越来越大的,但标签文字太小、线条太细,难以看清 楚。所幸Matplotlib让你能够调整可视化的各个方面。下面通过一些定制来改善这个图表的可读性,如下所示:

import matplotlib.pyplot as plt
squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(squares, linewidth=3)
 # 设置图表标题并给坐标轴加上标签。
ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)
 # 设置刻度标记的大小。
ax.tick_params(axis='both', labelsize=14)
plt.show()

①参数linewidth决定了plot() 绘制的线条粗细

②方法set_title() 给图表指定标题。

③方法set_xlabel() 和set_ylabel() 让你能够为每条轴设置标题。

④方 法tick_params()设置刻度的样式,其中指定的实参将影响 轴和 轴 上的刻度(axes='both' ),并将刻度标记的字号设置为14(labelsize=14 )。
1.2.2 校正图形

图形更容易看清后,我们发现没有正确地绘制数据:折线图的终点指出4.0的平方为 25!下面来修复这个问题。向 plot() 提供一系列数时,它假设第一个数据点对应的 坐标值为0,但这里第一 个点对应的值为1。为改变这种默认行为,可向plot() 同时提供输入值和输出值:

import matplotlib.pyplot as plt
input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(input_values, squares, linewidth=3)
# 设置图表标题并给坐标轴加上标签。
--snip

1.2.3使用内置样式

Matplotlib提供了很多已经定义好的样式,它们使用的背景色、网格线、线条粗 细、字体、字号等设置很不错,要获悉在你的系统中可使用哪些样式,可在终端会话中执行如下命令:

import matplotlib.pyplot as plt
plt.style.available

要使用这些样式,可在生成图表的代码前添加如下代码行:

import matplotlib.pyplot as plt
input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
plt.style.use('seaborn')
fig, ax = plt.subplots()
--snip

方法plt.style.use(样式),置于生成图标的代码前,就可按照自己喜欢的样式来生成图标。

1.2.4 使用scatter() 绘制散点图并设置样式

有时候,绘制散点图并设置各个数据点的样式很有用。要绘制单个点,可使用方法scatter() 。向它传递一对 坐标和 坐标,它将在指定位置绘制一个点:

import matplotlib.pyplot as plt
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.scatter(2, 4, s=200)
 # 设置图表标题并给坐标轴加上标签。
ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)
 # 设置刻度标记的大小。
ax.tick_params(axis='both', which='major', labelsize=14)
plt.show()

①调用scatter() 并使用参数 s 设置绘制图形时使用的点的尺寸。

1.2.5 使用scatter() 绘制一系列点

要绘制一系列的点,可向 scatter() 传递两个分别包含 值和 值的列表,如下所 示:

import matplotlib.pyplot as plt
x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.scatter(x_values, y_values, s=100)
# 设置图表标题并给坐标轴指定标签。
--snip

列表 x_values 包含要计算平方值的数,列表 y_values 包含前述数的平方值。将 这些列表传递给scatter() 时,Matplotlib依次从每个列表中读取一个值来绘制一个点。

1.2.6 自动计算数据

手工计算列表要包含的值可能效率低下,需要绘制的点很多时尤其如此。我们不必 手工计算包含点坐标的列表,可以用Python循环来完成。

import matplotlib.pyplot as plt
x_values = range(1, 1001)
y_values = [x**2 for x in x_values]
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.scatter(x_values, y_values, s=10)
 # 设置图表标题并给坐标轴加上标签。
 --snip--
 # 设置每个坐标轴的取值范围。
 ax.axis([0, 1100, 0, 1100000])
 plt.show()

使用方法axis() 指定了每个坐标轴的取值范围。方法axis() 要求提供4 个值: 和 坐标轴的最小值和最大值。这里将 坐标轴的取值范围设置为0~ 1100,并将 坐标轴的取值范围设置为0~1100 000。

1.2.7 自定义颜色

要修改数据点的颜色,可向 scatter() 传递参数 c ,并将其设置为要使用的颜色 的名称(放在引号内),如下所示:

ax.scatter(x_values, y_values, c='red', s=10)

11.2.8 使用颜色映射

颜色映射 (colormap)是一系列颜色,从起始颜色渐变到结束颜色。在可视化中, 颜色映射用于突出数据的规律。例如,你可能用较浅的颜色来显示较小的值,并使 用较深的颜色来显示较大的值。

import matplotlib.pyplot as plt 
x_values = range(1, 1001)
y_values = [x**2 for x in x_values]
ax.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=10) 
# 设置图表标题并给坐标轴加上标签。 --snip

我们将参数 c 设置成了一个 值列表,并使用参数 cmap 告诉 pyplot 使用哪个颜 色映射。这些代码将 值较小的点显示为浅蓝色,并将 值较大的点显示为深蓝色。

1.2.9 自动保存图表

要让程序自动将图表保存到文件中,可将调用plt.show() 替换为调用 plt.savefig()

plt.savefig('squares_plot.png', bbox_inches='tight')

第一个实参指定要以什么文件名保存图表,这个文件将存储到scatter_squares.py 所在的目录。第二个实参指定将图表多余的空白区域裁剪掉。如果要保留图表周围多余的空白区域,只需省略这个实参即可。

1.3 随机漫步

本节将使用Python来生成随机漫步数据,再使用Matplotlib以引人瞩目的方式将这 些数据呈现出来。随机漫步 是这样行走得到的路径:每次行走都是完全随机的、没 有明确的方向,结果是由一系列随机决策决定的。

1.3.1 创建RandomWalk 

为模拟随机漫步,将创建一个名为 RandomWalk 的类,它随机地选择前进方向。这 个类需要三个属性:一个是存储随机漫步次数的变量,其他两个是列表,分别存储 随机漫步经过的每个点的 坐标和坐标。

from random import choice
class RandomWalk: """一个生成随机漫步数据的类。"""
def __init__(self, num_points=5000):
 """初始化随机漫步的属性。"""
self.num_points = num_points #所有随机漫步都始于(0, 0)。 
self.x_values = [0]
self.y_values = [0]

并在每次决策时都使用模块random 中的choice() 来决定使用哪种选择

1.3.2 选择方向

我们将使用方法 fill_walk() 来生成漫步包含的点并决定每次漫步的方向,如下 所示。请将这个方法添加到random_walk.py中:

def fill_walk(self):
     """计算随机漫步包含的所有点。"""
         # 不断漫步,直到列表达到指定的长度。
    while len(self.x_values) < self.num_points:
         # 决定前进方向以及沿这个方向前进的距离。
     x_direction = choice([1, -1])
     x_distance = choice([0, 1, 2, 3, 4])
     x_step = x_direction * x_distance
     y_direction = choice([1, -1])
     y_distance = choice([0, 1, 2, 3, 4])
     y_step = y_direction * y_distance
     # 拒绝原地踏步。
    if x_step == 0 and y_step == 0:
     continue
     # 计算下一个点的x值和y值。
    x = self.x_values[-1] + x_step
    y = self.y_values[-1] + y_step
    self.x_values.append(x)
    self.y_values.append(y)

①使用choice([1, -1]) 给x_direction 选择一个值,结果要么是表示向右走的 1,要么是表示向左走的-1.
②choice([0, 1, 2, 3, 4]) 随机 地选择一个0~4的整数,告诉Python 沿指定的方向走多(x_distance )。
③将移动方向乘以移动距离,确定沿X轴和Y轴移动的距离。

1.3.3 绘制随机漫步图

下面的代码将随机漫步的所有点都绘制出来:

import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 创建一个RandomWalk实例。
rw = RandomWalk()
rw.fill_walk()
# 将所有的点都绘制出来。
plt.style.use('classic')
fig, ax = plt.subplots()
ax.scatter(rw.x_values, rw.y_values, s=15)
plt.show()

将随机漫步包含的X值和Y传递给scatter() ,并选择合适的点尺寸 。

1.3.4 设置随机漫步图的样式

a. 给点着色
我们将使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮 廓,让其颜色更为明显。为根据漫步中各点的先后顺序来着色,传递参数c , 并将其设置为一个列表,其中包含各点的先后顺序。这些点是按顺序绘制的, 因此给参数c 指定的列表只需包含数0~4999,如下所示:

--snip--
while True:
# 创建一个RandomWalk实例。
rw = RandomWalk()
rw.fill_walk()
# 将所有的点都绘制出来。
plt.style.use('classic')
fig, ax = plt.subplots()
point_numbers = range(rw.num_points)
ax.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues,
edgecolors='none', s=15)
keep_running = input("Make another walk? (y/n): ")
 --snip--

①使用range() 生成了一个数字列表,其中包含的数与漫步包含的点数量相同。

②并传递实参edgecolors='none'

③将参数c 设置为point_numbers ,指定使用颜色映射Blues

b. 重新绘制起点和终点

--snip--
while True:
    --snip--
     ax.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
     edgecolors='none', s=15)
     # 突出起点和终点。
     ax.scatter(0, 0, c='green', edgecolors='none', s=100)
     ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
         s=100)
     plt.show()
             --snip--

使用绿色绘制点(0, 0),并使其比其他点大(s=100 )。为突出终点,在漫步包含的最后一个 值和 值处绘制一个点,将其颜色设置为红 色,并将尺寸设置为100。务必将这些代码放在调用plt.show() 的代码前面,确保在其他点之上绘制起点和终点。

c. 隐藏坐标轴

# 隐藏坐标轴。
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

使用方法ax.get_xaxis() 和ax.get_yaxis() 将 每条坐标轴的可见性都设置为False 。 随着对数据可视化的不断学习和实践, 你会经常看到这种串接方法的方式。

d 调整尺寸以适合屏幕

--snip--
while True:
 # 创建一个RandomWalk实例。
 rw = RandomWalk(50_000)
 rw.fill_walk()
 # 将所有的点都绘制出来。
 plt.style.use('classic')
 fig, ax = plt.subplots(figsize=(15, 9))
 --snip--

可传递参数figsize 以指定生成的图形的尺寸。需要给参数 figsize 指定一个元组,向Matplotlib指出绘图窗口的尺寸.

1.4 使用Plotly模拟掷骰子

本节将使用Python包Plotly来生成交互式图表。

1.4.1 安装Plotly

在终端输入:

 python -m pip install --user plotly

即可安装plotiy

1.4.2 创建Die 

from random import randint
     class Die:
         """表示一个骰子的类。"""
         def __init__(self, num_sides=6):
             """骰子默认为6面。"""
             self.num_sides = num_sides
         def roll(self):
         """"返回一个位于1和骰子面数之间的随机值。"""
             return randint(1, self.num_sides)

①方法__init__() 接受一个可选参数。创建这个类的实例时,如果没有指定任何实
参,面数默认为6;
②方法roll() 使用函数randint() 来返回一个1和面数之间的随机数。这 个函数可能返回起始值1、终止值num_sides 或这两个值之间的任何整数。
有时我们使用这个类会出现错误,此时我们可以只定义roll函数,不去定义类。

1.4.3 掷骰子

使用这个类来创建图表前,先来掷D6,将结果打印出来,并确认结果是合理的:

from die import Die
 # 创建一个D6。 ❶ die = Die()
 # 掷几次骰子并将结果存储在一个列表中。
results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)
print(results)

1.4.4 分析结果

为分析掷一个D6的结果,计算每个点数出现的次数:

 --snip--
 # 掷几次骰子并将结果存储在一个列表中。
 results = []
for roll_num in range(1000):
     result = die.roll()
     results.append(result)
     # 分析结果。
frequencies = []
for value in range(1, die.num_sides+1):
frequency = results.count(value)
frequencies.append(frequency)
     print(frequencies)

由于将使用Plotly来分析,而不是将结果打印出来,因此可将模拟掷骰子的次数增 加到1000 。为分析结果,我们创建空列表 frequencies ,用于存储每种 点数出现的次数。在 处,遍历可能的点数(这里为1~6),计算每种点数在 results 中出现了多少次。

1.4.5 绘制直方图

有了频率列表,就可以绘制一个表示结果的直方图了。 直方图 是一种条形图,指出 了各种结果出现的频率。

from plotly.graph_objs import Bar, Layout
from plotly import offline
from die import Die
 --snip--
 # 分析结果。
frequencies = []
for value in range(1, die.num_sides+1):
    frequency = results.count(value)
    frequencies.append(frequency)
 # 对结果进行可视化。
x_values = list(range(1, die.num_sides+1))
data = [Bar(x=x_values, y=frequencies)]
x_axis_config = {'title': '结果'}
y_axis_config = {'title': '结果的频率'}
my_layout = Layout(title='掷一个D6 1000次的结果',
xaxis=x_axis_config, yaxis=y_axis_config)
offline.plot({'data': data, 'layout': my_layout}, filename='d6.html')

①我们将可能出现的点数 (1到骰子的面数)存储在一个名为x_values 的列表中,Plotly不能直接 接受函数range() 的结果,因此需要使用函数list() 将其转换为列表。

②Plotly类 Bar() 表示用于绘制条形图的数据集,需要一个存储X值的列表和一个存储Y值的列表。这个类必须放在方括号内,因为数据集可能包含多个元素。

③类Layout() 返回一个指定图表布局和配置的对象 (见❹)。这里设置了图表名称,并传入了 轴和 轴的配置字典。

④这个函数需要一个包含 数据和布局对象的字典,还接受一个文件名,指定要将图表保存到哪里。这里将输 出存储到文件d6.html。

第二章 下载数据

本章将从网上下载数据,并对其进行可视化。本章将访问并可视化的数据以两种常见格式存储:CSV和JSON。

2.1CSV文件格式

要在文本文件中存储数据,一个简单方式是将数据作为一系列 以逗号分隔的值(comma-separated values)写入文件。这样的文件成为CVS文件。

2.1.1 分析CSV文件头

csv 模块包含在Python标准库中,可用于分析CSV文件中的数据行,让我们能够快速 提取感兴趣的值。(它相当于一个竖着排列的一列列的列表,而开头一行是列表名)。接下来我们尝试读取这些列表名。
import csv
filename = 'data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    print(header_row)

将文件名赋给filename,这是打开文件时常用的做法。然后将用到至关重要的函数csv.reader(),括号里包含的是需要读取的文件对象,从而创建一个与该文件相关联的阅读器对象,在这里被赋给了reader。模块csv 包含函数next() ,调用它并传入阅读器对象时,它将返回文件中的下一 行。在上述代码中,只调用了next() 一次,因此得到的是文件的第一行,其中包含文件头。

注意:当阅读器经过next()函数以后,每当调用一次将会自动返回文件的下一行。

2.1.2打印开头及其位置

为了得到文件头下包含的数据,我们需要获取文件头的位置。于是接着上面代码的基础上我们再加几行代码:

import csv
filename = 'data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)
for index,name in enumerate(header_row)
    print(index,name)

在这里我们又引用了一个新的函数enumerate(),有点类似于对于字典使用的items()这个函数,不同的是这里返回的是索引和元素。由此我们获得了对应文件的开头,方便我们获得需要的数据。

2.1.3读取并提取文件

知道了第一行里对应的数据名以及位置,我们可以回去剩下行里的数据。

with open(filename) as f:
     reader = csv.reader(f)
     header_row = next(reader)
     # 从文件中获取最高温度。
        highs = []
    for row in reader:
        high = int(row[5])
         highs.append(high)
print(highs)

紧接着上面的代码我们获取每一行数据的第五个索引位置的数据(最高温度)。

2.1.4绘制温度图表

为了将数据可视化,我们使用上面安装的用Matplotlib创建一个显示每日最高温度的简单图 形,如下所示:

import csv
import matplotlib.pyplot as plt
filename = 'data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
--_snip_—
# 根据最高温度绘制图形。
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(highs, c='red')
# 设置图形的格式。
ax.set_title("2018年7月每日最高温度", fontsize=24)
ax.set_xlabel('', fontsize=16)
ax.set_ylabel("温度 (F)", fontsize=16)
ax.tick_params(axis='both', which='major', labelsize=16)
plt.show()

使用绘图函数plot(),并传递c="red",以便将数据点绘制为红色,其余函数在上一章均详细介绍过,

2 .1.5 模块datetime

根据前面获取的第一行文件名,我们来获取详尽的时间,读取该数据时,获得的是一个字符串,因此需要想办法将字符串"2018-7-1" 转换 为一个表示相应日期的对象。为此我们再此使用新的函数,datetime模块中的的方法strptime(),下面演示此函数作用:

>>> from datetime import datetime
>>> first_date = datetime.strptime('2018-07-01', '%Y-%m-%d')
>>> print(first_date)
2018-07-01 00:00:00
首先导入模块 datetime 中的 datetime 类,再调用方法 strptime() ,并将包 含所需日期的字符串作为第一个实参。第二个实参告诉Python如何设置日期的格 式。在这里,'%Y-' 让Python将字符串中第一个连字符前面的部分视为四位的年 份,'%m-' 让Python将第二个连字符前面的部分视为表示月份的数, '%d' 让 Python将字符串的最后一部分视为月份中的一天(1~31)。
方法 strptime() 可接受各种实参,并根据它们来决定如何解读日期。下表列出 了这样的一些实参。
实参 含义
%A 星期几,,如Monday
%B
月份名,如January
%m
用数表示的月份(01~12)
%d
用数表示的月份中的一天(01~31)
%
四位的年份,如2019
%
两位的年份,如19
%
24小时制的小时数(00~23)
%
12小时制的小时数(01~12)
%
am或pm
%
分钟数(00~59)

2.1.6在图表中添加日期

现在,可以通过提取日期和最高温度并将其传递给 plot() ,对温度图形进行改 进,如下所示:
import csv
from datetime import datetime
import matplotlib.pyplot as plt
filename = 'data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
  reader = csv.reader(f)
  header_row = next(reader)
  # 从文件中获取日期和最高温度。
dates, highs = [], []
for row in reader:
   current_date = datetime.strptime(row[2], '%Y-%m-%d')
   high = int(row[5])
   dates.append(current_date)
   highs.append(high)
 # 根据最高温度绘制图形。
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(dates, highs, c='red')
# 设置图形的格式。
ax.set_title("2018年7月每日最高温度", fontsize=24)
ax.set_xlabel('', fontsize=16)
fig.autofmt_xdate()
ax.set_ylabel("温度 (F)", fontsize=16)
ax.tick_params(axis='both', which='major', labelsize=16)
plt.show()

2.1.7再绘制一个数据系列

虽然改进后的图表已经显示了丰富的数据,但是还能再添加最低温度数据,使其更 有用。为此,需要从数据文件中提取最低温度,并将它们添加到图表中,如下所示:
 --snip--
 filename = 'sitka_weather_2018_simple.csv'
 with open(filename) as f:
     reader = csv.reader(f)
     header_row = next(reader)
     # 从文件中获取日期、最高温度和最低温度。
 dates, highs, lows = [], [], []
 for row in reader:
     current_date = datetime.strptime(row[2], '%Y-%m-%d')
     high = int(row[5])
     low = int(row[6])
 dates.append(current_date)
 highs.append(high)
 lows.append(low)
 # 根据最高温度和最低温度绘制图形。
 plt.style.use('seaborn')
 fig, ax = plt.subplots()
 ax.plot(dates, highs, c='red')
 ax.plot(dates, lows, c='blue')
 # 设置图形的格式。
 ax.set_title("2018年每日最高温度", fontsize=24)
 --snip--
添加空列表 lows ,用于存储最低温度。接下来,从每行的第七列 row[6] )提取最低温度并存储 添加调用 plot() 的代码,以 使用蓝色绘制最低温度。

2.1.8给图表区域着色

添加两个数据系列后,就可以知道每天的温度范围了。下面来给这个图表做最后的 修饰,通过着色来呈现每天的温度范围。
--snip--
 # 根据最低温度和最高温度绘制图形。
 plt.style.use('seaborn')
 fig, ax = plt.subplots()
 ax.plot(dates, highs, c='red', alpha=0.5)
 ax.plot(dates, lows, c='blue', alpha=0.5)
 ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
 --snip--

我们再此引用函数方法fill_between() 。 它接受一个 值系列和两个 值系列,并填充两个 值系列之间的空间。实参alpha 指定颜色的透明度。alpha 值为0表示完全透明,为1(默认设置表示完全不透明。向fill_between() 传递一个 值系列(列表dates ),以及两个 值 系列(highs lows )。实参facecolor指定填充区域的颜色,还将alpha 设置成了较小的值0.1。

2.2制作全球地震散点图:JSON格式

你将下载一个数据集,其中记录了一个月内全球发生的所有地震,再 制作一幅散点图来展示这些地震的位置和震级。这些数据是以JSON格式存储的,因 此要使用模块json 来处理。

2.1.1地震数据

请将文件eq_data_1_day_m1.json复制到存储本章程序的文件夹中。地震是以里氏震 级度量的,而该文件记录了(截至写作本节时)最近24小时内全球发生的所有不低 于1级的地震。

2.2.2 查看JSON数据

如果打开文件eq_data_1_day_m1.json,你将发现其内容密密麻麻,难以阅读,这些数据适合机器而不是人来读取。不过可以看到,这个文件包含一些字典,还有一些我们感兴趣的信息,如震级和位置。 块json 提供了各种探索和处理JSON数据的工具,其中一些有助于重新设置这个 文件的格式,让我们能够更清楚地查看原始数据,继而决定如何以编程的方式来处理。
import json
# 探索数据的结构。
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
    all_eq_data = json.load(f)
    readable_file = 'data/readable_eq_data.json'
with open(readable_file, 'w') as f:
    json.dump(all_eq_data, f, indent=4)
首先导入模块 json ,以便恰当地加载文件中的数据,并将其存储到 all_eq_data 中 。函 json.load() 将数据转换为Python能够处理的格式,这里是一 个庞大的字典。 创建一个文件,以便将这些数据以易于阅读的方式写入其 中。函数json.dump() 接受一个JSON数据对象和一个文件对象,并将数据写入这 个文件中 。参数 indent=4 dump() 使用与数据结构匹配的缩进量来设 置数据的格式。

2.2.3 创建地震列表

首先,创建一个列表,其中包含所有地震的各种信息:
import json
# 探索数据的结构。
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
    all_eq_data = json.load(f)
    all_eq_dicts = all_eq_data['features']
print(len(all_eq_dicts))
我们提取与键 'features' 相关联的数据,并将其存储到 all_eq_dicts 中。我 们知道,这个文件记录了158次地震。下面的输出表明,我们提取了这个文件记录的所有地震。

2.2.4 提取震级

有了包含所有地震数据的列表后,就可遍历这个列表,从中提取所需的数据。下面
来提取每次地震的震级:
--snip--
all_eq_dicts = all_eq_data['features']
mags = []
for eq_dict in all_eq_dicts:
     mag = eq_dict['properties']['mag']
     mags.append(mag)
print(mags[:10])

2.2.5 提取位置数据并绘制震级散点图

位置数据存储在 "geometry" 键下。在 "geometry" 键关联的字典中,有一 个"coordinates" 键,它关联到一个列表,而列表中的前两个值为经度和纬度。有了前面提取的数据,就可以绘制可视化图了。首先要实现一个简单的震级散点图,在确保显示的信息正确无误之后,我们再将注意力转向样式和外观方面。绘制初始散点图的代码如下:
 import plotly.express as px
 fig = px.scatter(
 x=lons,
 y=lats,
 labels={"x": "经度", "y": "纬度"},
 range_x=[-200, 200],
 range_y=[-90, 90],
 width=800,
 height=800,
 title="全球地震散点图",
)
 fig.write_html("global_earthquakes.html")
 fig.show()
导入 plotly.express ,用别名 px 表示。Plotly Express是Plotly的高级接口。
调用 px.scatter 函数 配置参数创建一个fig 实例,分别设置 轴为经度[范围是 [-200, 200] (扩大 空间,以便完整显示东西经180°附近的地震散点)]、 轴为纬度[范围是[-90, 90] ],设置散点图显示的宽度和高度均为800像素,并设置标题为“全球地震散点图。

2.2.6 另一种指定图表数据的方式

下面是另一种给图表定义数据的等效方式,需要使用pandas数据分析工 具。首先创建一个DataFrame ,将需要的数据封装起来:
import pandas as pd
data = pd.DataFrame(
 data=zip(lons, lats, titles, mags), columns=["经度", "纬度", "位置", "震级"]
)
data.head(
在这种方式中,所有有关数据的信息都以键值对的形式放在一个字典中。如果在
eq_plot.py中使用这些代码,生成的图表是一样的。相比于前一种格式,这种格式
让我们能够无缝衔接数据分析,并且更轻松地进行定制。

2.2.7 定制标记的尺寸

确定如何改进散点图的样式时,应着重于让要传达的信息更清晰。当前的散点图显 示了每次地震的位置,但没有指出震级。我们要让观察者迅速获悉最严重的地震发生在什么地方。为此,根据地震的震级设置其标记的尺寸:
fig = px.scatter(
 data,
 x="经度",
 y="纬度",
 range_x=[-200, 200],
 range_y=[-90, 90],
 width=800,
 height=800,
 title="全球地震散点图",
 size="震级",
 size_max=10,
 )
 fig.write_html("global_earthquakes.html")
 fig.show()
Plotly Express支持对数据系列进行定制,这些定制都以参数表示。这里使用了 size 参数来指定散点图中每个标记的尺寸,我们只需要将前面 data 中的 " 震级 " 字段提供给size 参数即可。标记尺寸默认为20像素,还可以通过size_max=10 将最大显示尺寸缩放到10。

2.2.8 定制标记的颜色

为了让标记的震级按照不同的颜色 显示,只需要配置color=" 震级 " 即可。默认的视觉映射图例渐变色范围是从蓝到红再到黄,数值越小则标记越蓝,而数值越大则标记越黄。
 filename = 'data/eq_data_30_day_m1.json'
 --snip--
 fig = px.scatter(
 data,
 x="经度",
 y="纬度",
 range_x=[-200, 200],
 range_y=[-90, 90],
 width=800,
 height=800,
 title="全球地震散点图",
 size="震级",
 size_max=10,
 color="震级
)

你可能感兴趣的:(Python,python,开发语言)