在今天晚上的学习中,我将继续完善昨晚所做的天气图。

3.2 添加更多的数据:

设置好图表后,我们来添加更多的数据,以成一幅更复杂的天气图:

3.2.1 涵盖更长的时间:

现在可以创建覆盖整年的天气图了:

python绘制天气变化图 python天气可视化_数据分析

# -*- coding:utf-8 -*-

import csv

from matplotlib import pyplot as plt
from datetime import datetime

# 从文件中获取日期和最高气温
filename =  'sitka_weather_2014.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[0], "%Y-%m-%d")
		dates.append(current_date)

		high = int(row[1])
		highs.append(high)

	print(highs)

# 根据数据绘制图形
fig = plt.figure(dpi=127, figsize=(10, 6))
plt.plot(dates,highs, c='red')

# 设置图形的格式
plt.title('Daily high temperature - 2014',  fontsize=23)
plt.xlabel('', fontsize=17)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)', fontsize=17)
plt.tick_params(axis='both', which='major', labelsize=17)

plt.show()

我们修改了文件名,以使用新的数据文件sitka_weather_2014.csv(见第9行);我们还修改了图表的标题,以反映其内容的变化(见第30行)。下图显示了生成的图形:

python绘制天气变化图 python天气可视化_数据可视化_02

3.2.2 再绘制一个数据:

上图所示的改进后的图表显示了大量意义深远的数据,但我们可以在其中再添加最低气温数据,使其更有用。为此,需要从数据文件中提取最低气温,并将它们添加到图表中,如下所示:

python绘制天气变化图 python天气可视化_数据分析_03

# -*- coding:utf-8 -*-

import csv

from matplotlib import pyplot as plt
from datetime import datetime

# 从文件中获取日期和最高气温
filename =  'sitka_weather_2014.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[0], "%Y-%m-%d")
		dates.append(current_date)

		high = int(row[1])
		highs.append(high)

		low = int(row[3])
		lows.append(low)

	print(highs)
	print(lows)

# 根据数据绘制图形
fig = plt.figure(dpi=127, figsize=(10, 6))
plt.plot(dates,highs, c='red')
plt.plot(dates,lows, c='blue')

# 设置图形的格式
plt.title('Daily high and low temperature - 2014',  fontsize=23)
plt.xlabel('', fontsize=17)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)', fontsize=17)
plt.tick_params(axis='both', which='major', labelsize=17)

plt.show()

在第14行处,我们添加了空列表lows ,用于存储最低气温。接下来,我们从每行的第4列(row[3] )提取每天的最低气温,并存储它们(见23-24行)。在第32行处,我们添加了一个对plot() 的调用,以使用蓝色绘制最低气温。最后,我们修改了标题(见第35行)。下图显示了这样绘制出来的图表:

python绘制天气变化图 python天气可视化_数据分析_04

3.2.3 给图表区域着色:

添加两个数据系列后,我们就可以了解每天的气温范围了。下面来给这个图表做最后的修饰,通过着色来呈现每天的气温范围。为此,我们将使用方法fill_between() ,它接受一个 x 值系列和两个 y 值系列,并填充两个 y 值系列之间的空间:

python绘制天气变化图 python天气可视化_数据分析_05

# -*- coding:utf-8 -*-

import csv

from matplotlib import pyplot as plt
from datetime import datetime

# 从文件中获取日期和最高气温
filename =  'sitka_weather_2014.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[0], "%Y-%m-%d")
		dates.append(current_date)

		high = int(row[1])
		highs.append(high)

		low = int(row[3])
		lows.append(low)

	print(highs)
	print(lows)

# 根据数据绘制图形
fig = plt.figure(dpi=127, figsize=(10, 6))
plt.plot(dates,highs, c='red',alpha=0.5)
plt.plot(dates,lows, c='blue',alpha=0.5)
plt.fill_between(dates, highs ,lows, facecolor='green', alpha=0.2)

# 设置图形的格式
plt.title('Daily high and low temperature - 2014',  fontsize=23)
plt.xlabel('', fontsize=17)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)', fontsize=17)
plt.tick_params(axis='both', which='major', labelsize=17)

plt.show()

31-32行处的实参alpha 指定颜色的透明度。Alpha 值为0表示完全透明,1(默认设置)表示完全不透明。通过将alpha 设置为0.5,可让红色和蓝色折线的颜色看起来更浅。 在第33行处,我们向fill_between() 传递了一个 x 值系列:列表dates ,还传递了两个 y 值系列:highslows 。实参facecolor 指定了填充区域的颜色,我还将alpha 设置成了较小的值0.2,让填充区域将两个数据系列连接起来的同时不分散观察者的注意力。下图显示了最高气温和最低气温之间的区域被填充的图表,通过着色,让两个数据集之间的区域显而易见:

python绘制天气变化图 python天气可视化_数据可视化_06

3.2.4 对错误进行检查:

我们应该能够使用有关任何地方的天气数据来运行highs_lows.py中的代码,但有些气象站会偶尔出现故障,未能收集部分或全部其应该收集的数据。缺失数据可能会引发异常,如果不妥善地处理,可能导致程序崩溃。例如,我们来看看下面这个例子出现的情况:

python绘制天气变化图 python天气可视化_数据分析_07

# -*- coding:utf-8 -*-

import csv

from matplotlib import pyplot as plt
from datetime import datetime

# 从文件中获取日期和最高气温
filename =  'death_valley_2014.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[0], "%Y-%m-%d")
		dates.append(current_date)

		high = int(row[1])
		highs.append(high)

		low = int(row[3])
		lows.append(low)

	print(highs)
	print(lows)

# 根据数据绘制图形
fig = plt.figure(dpi=127, figsize=(10, 6))
plt.plot(dates,highs, c='red',alpha=0.5)
plt.plot(dates,lows, c='blue',alpha=0.5)
plt.fill_between(dates, highs ,lows, facecolor='green', alpha=0.2)

# 设置图形的格式
plt.title('Daily high and low temperature - 2014',  fontsize=23)
plt.xlabel('', fontsize=17)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)', fontsize=17)
plt.tick_params(axis='both', which='major', labelsize=17)

plt.show()

运行这个程序时,出现了一个错误,如上述输出的最后一行所示:该traceback指出,Python无法处理其中一天的最高气温,因为它无法将空字符串(' ' )转换为整数。只要看一下death_valley_2014.csv,就能发现其中的问题:

python绘制天气变化图 python天气可视化_python_08

其中好像没有记录2014年2月16日的数据,表示最高温度的字符串为空。为解决这种问题,我们在从CSV文件中读取值时执行错误检查代码,对分析数据集时可能出现的异常进行处理,如下所示:

python绘制天气变化图 python天气可视化_python绘制天气变化图_09

# -*- coding:utf-8 -*-

import csv

from matplotlib import pyplot as plt
from datetime import datetime

# 从文件中获取日期和最高气温
filename =  'death_valley_2014.csv'
with open(filename) as f:
	reader = csv.reader(f)
	header_row = next(reader)

	dates, highs, lows=[],[],[]

	for row in reader:
		try:
			current_date = datetime.strptime(row[0], "%Y-%m-%d")
			low = int(row[3])
			high = int(row[1])
			
		except ValueError:
			print(current_date, 'missing data')

		else:
			dates.append(current_date)
			highs.append(high)
			lows.append(low)


# 根据数据绘制图形
fig = plt.figure(dpi=127, figsize=(10, 6))
plt.plot(dates,highs, c='red',alpha=0.5)
plt.plot(dates,lows, c='blue',alpha=0.5)
plt.fill_between(dates, highs ,lows, facecolor='green', alpha=0.2)

# 设置图形的格式
plt.title('Daily high and low temperature - 2014',  fontsize=23)
plt.xlabel('', fontsize=17)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)', fontsize=17)
plt.tick_params(axis='both', which='major', labelsize=17)

plt.show()

对于每一行,我们都尝试从中提取日期、最高气温和最低气温(见第17行)。只要缺失其中一项数据,Python就会引发ValueError 异常,而我们可这样处理:打印一条错误消息, 指出缺失数据的日期(见22-23行)。打印错误消息后,循环将接着处理下一行。如果获取特定日期的所有数据时没有发生错误,将运行else 代码块,并将数据附加到相应列表的末尾(见第25-28行)。如果现在运行highs_lows.py ,如上图所示,将发现缺失数据的日期只有一个。

使用的很多数据集都可能缺失数据、数据格式不正确或数据本身不正确。在这里,我们使用了一个try-except- else 代码块来处理数据缺失的问题。在有些情况下,需要使用continue 来跳过一些数据,或者使用remove()del 将已提取的数据删除。