CSV以及JSON格式的数据可视化

文章目录

  • 1. CSV格式文件数据可视化
    • 1.1 打印文件头以及位置
    • 1.2 提取并读取数据
    • 1.3 绘制全年的温度图表
      • 1.3.1 在图表中添加日期
      • 1.3.2 给图表区域上色
    • 1.4 数据错误检查
  • 2. JSON格式文件数据可视化-制作全球地震散点图
    • 2.1 查看JSON数据
    • 2.2 创建数据列表以及提取数据
    • 2.3 数据的可视化(绘制震级散点图)
      • 2.3.1 pandas 定义图表数据
      • 2.3.2 定制标记的尺寸、添加颜色
      • 2.3.3 添加鼠标指向时显示的文本(地震位置)

1. CSV格式文件数据可视化


1.1 打印文件头以及位置

导入模块 csv ,将要使用的文件的名称赋给 filename。接下来,打开这个文件,并将返回的文件对象赋给 f 。

import csv

# 将文件放在工程文件夹,在同一个路径下,不需要添加绝对路径
filename = 'sitka_weather_07-2018_simple.csv'  
# 注意一点,接下来的操作是在打开这份文件的基础上进行的,所以要注意缩进
with open(filename) as f:                      
    reader = csv.reader(f)
    header_row = next(reader) # next()返回文件中的下一行
    print(header_row)	# 打印表头
    # 获取每个元素的索引及其值
    for index,column_header in enumerate(header_row):   
        print(index,column_header)

输出结果:可以看出通过**enumerate()**我们获取元素的索引,以便我们接下来对文件中数据的处理

['STATION', 'NAME', 'DATE', 'PRCP', 'TAVG', 'TMAX', 'TMIN']
0 STATION
1 NAME
2 DATE
3 PRCP
4 TAVG
5 TMAX
6 TMIN


1.2 提取并读取数据

当我们通过上述方法获取文件中的表头以及索引号之后,接下来就是对文件数据的处理。

在这里对 row 感觉有点疑惑,在循环中表示行,但在提取数据时是列。

 --snip--
 with open(filename) as f:                      
    reader = csv.reader(f)
    header_row = next(reader)
 # 从文件中获取最高的温度
    highs = []
    for row in reader:	# 遍历文件中余下的各行
        high = int(row[5])	# row()默认是列
        highs.append(high)
 print(highs)

输出结果:通过列表形式输出,这样就可以可视化这些数据了

[62, 58, 70, 70, 67, 59, 58, 62, 66, 59, 56, 63, 65, 58, 56, 59, 64, 60, 60, 61, 65, 65, 63, 59, 64, 65, 68, 66, 64, 67, 65]

1.3 绘制全年的温度图表

其中包含最低、最高温度两条折线图,以及他们之间的区域
在这里关于 Matplotlib 制图就不再赘述

import csv
# datetime模块中的类
from datetime import datetime
import matplotlib.pyplot as plt

filename = 'sitka_weather_2018_simple.csv'   
with open(filename) as f:                      
	--snip--

	# 从文件中获取日期、最高温度和最低温度
    dates, highs, lows = [], [], []
    # 书本306模块date设置时间日期格式的实参
    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()
    # alpha指定颜色的透明度
    ax.plot(dates, highs, c='red', alpha=0.5)                    
    ax.plot(dates, lows, c='blue', alpha=0.5)
    # facecolor填充颜色
    ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)    
    # 设置图形的格式
    ax.set_title("2018DTMAX-MIN")
    ax.set_xlabel('', fontsize=16)
    # 绘制倾斜的 X 轴日期标签,以免重叠
    fig.autofmt_xdate()
    ax.set_ylabel('T(F)', fontsize=16)
    # 设置刻度的样式和大小
    ax.tick_params(axis='both', which='major', labelsize=16)
    
plt.show()

图表输出如下:
CSV以及JSON格式的数据可视化_第1张图片

1.3.1 在图表中添加日期

添加日期是通过模块 datetime 中的方法 strptime()
方法 **strptime()**可接受各种的实参,并根据他们来决定如何解读日期

--snip--

 # 从文件中获取日期、最高温度和最低温度
    dates, highs, lows = [], [], []
    # 通过通过模块和方法我们能解读文件中的日期
    # '%Y-' 将第一个连字符前面的部分视为四位的年份
    # '%m-' 将第二个连字符前面的部分视为月份的数
    # '%d-' 将字符串最后一部分视为月份中的一天
    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)

ax.plot(dates, highs, c='red', alpha=0.5) # dates就表示X轴数据

--snip--

1.3.2 给图表区域上色

将使用方法 fill_between() 来填充两个y值之间的空间,使得图表中的数据更加的可视化

--snip--
	# 根据最高温度和最低温度绘制图形
    plt.style.use('seaborn')
    fig, ax = plt.subplots()
    # alpha指定颜色的透明度
    ax.plot(dates, highs, c='red', alpha=0.5)
    ax.plot(dates, lows, c='blue', alpha=0.5)
    # facecolor填充颜色
    ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
--snip--

效果图如下:数据点的颜色以及填充色都是可以修改透明度
CSV以及JSON格式的数据可视化_第2张图片

1.4 数据错误检查

由于缺失数据可能引发异常,如果不妥善处理,可能导致程序崩溃

--snip--
    # 从文件中获取最高的温度
    highs = []
    for row in reader:
        high = int(row[5])
        highs.append(high)
    print(highs)
--snip--    

在运行以上程序时出现了错误,如下述输出的最后一行所示:

Traceback (most recent call last):
  File "csv_file_t.py", line 15, in <module>
    high = int(row[5])
ValueError: invalid literal for int() with base 10: ''

该 Traceback 指出,Python无法处理其中一天的 最高温度,因为无法将空字符(’ ')转换为整数


为此,在从CSV文件中读取值时执行错误检查代码,对可能出现的异常进行处理,如下所示:

--snip--
dates, highs, lows = [], [], []
    for row in reader:
        current_date = datetime.strptime(row[2], '%Y/%m/%d')
        try:
            high = int(row[5])
            low = int(row[6])
        except ValueError:
            print(f"Missing data for {current_date}")
        else:
            dates.append(current_date)
            highs.append(high)
            lows.append(low)
--snip--            

只要缺失其中一项数据,Python就会引发 ValueError 异常。我们这样进行处理:打印一条错误信息,指出缺失数据的日期。之后循环将接着处理下一行数据。

缺失数据输出如下:

Missing data for 2018-01-01 00:00:00


2. JSON格式文件数据可视化-制作全球地震散点图

本节主要实现的功能是:制作全球地震散点图

2.1 查看JSON数据

函数 json.load() 将数据转化为Python能够处理的格式,是一个庞大的字典文件,随后我们创建一个新的文件将数据存入其中。

函数 json.dump() 接受一个JSON数据对象和一个文件对象,并将数据写入这个文件中。参数 indent=4dump() 使用与数据结构匹配的缩进量来设置数据的格式。

import json
# 我理解的思路是:先转换格式,再存入新的文件
# 探索数据的结构
filename = 'eq_data_1_day_m1.json'
with open(filename) as f:
    all_eq_data = json.load(f)

# 创建一个新的空json文件
readable_file = 'readable_eq_data.json'
# 打开刚才新创建的文件,写入模式
with open(readable_file, 'w') as f:
    json.dump(all_eq_data, f, indent=4)

文件 readable_eq_data.json 数据如下图显示:
这个文件的数据看不明白(字典嵌套列表 / 列表嵌套字典)

CSV以及JSON格式的数据可视化_第3张图片

2.2 创建数据列表以及提取数据

据上一小节描述以及图片,我们得知 JSON数据 是一个庞大的 字典文件 。现在,我们创建一个列表存储所有地震的各种信息,并提取其中的震级。

其中疑惑的是:all_eq_dicts = all_eq_data[‘features’]
为什么 all_eq_dicts 是一个列表?

import json

filename = 'eq_data_1_day_m1.json'
with open(filename) as f:
    all_eq_data = json.load(f)

# 提取与键 'features' 相关联的数据
all_eq_dicts = all_eq_data['features']
print(len(all_eq_dicts)) # 

# 提取:震级, 存储位置的标题, 经度, 纬度
mags, titles, lons, lats = [], [], [], []
#遍历列表
for eq_dict in all_eq_dicts:
    # 字典'properties'中的'mag'键的值就是震级
    # 字典'geomrtey'中的'coordinates'键的第一、二个值就是经纬度
    mag = eq_dict['properties']['mag']
    title = eq_dict['properties']['title']
    lon = eq_dict['geometry']['coordinates'][0]
    lat = eq_dict['geometry']['coordinates'][1]
    mags.append(mag)
    titles.append(title)
    lons.append(lon)
    lats.append(lat)
    
print(mags[:10])
print(titles[:2])
print(lons[:5])
print(lats[:5])

输出结果:文件数据都提取正常,接下来就是进行数据可视化

输出结果:
158 # 表明这个文件记录了158次地震
[0.96, 1.2, 4.3, 3.6, 2.1, 4, 1.06, 2.3, 4.9, 1.8]
['M 1.0 - 8km NE of Aguanga, CA', 'M 1.2 - 11km NNE of North Nenana, Alaska']
[-116.7941667, -148.9865, -74.2343, -161.6801, -118.5316667]
[33.4863333, 64.6673, -12.1025, 54.2232, 35.3098333]

2.3 数据的可视化(绘制震级散点图)

首先要实现一个简单的震级散点图,之后随着代码不断的完善再补充内容
在这里 Plotly 制图就不再赘述,语法与 Matplotlib 类似
这里所用的是 Plotly Express 来定义图表数据

import plotly.express as px

fig = px.scatter(
    x=lons,
    y=lats,
    labels={'x': '经度', 'y': '纬度'},
    range_x=[-200,200],	# x,y轴的取值范围
    range_y=[-200,200], 
    width=800,			# 散点图显示的高度,宽度设置为800像素
    height=800,
    title='全球地震散点图'
)
# fig.write_html 方法将可视化图保存为html文件
fig.write_html('global_earthquakes.html')
fig.show()

global_earthquakes.html 图片如下:

我们可以看出现在的可视化图提供给我们的数据还是很有限的,所以接下来我们将继续完善
CSV以及JSON格式的数据可视化_第4张图片

2.3.1 pandas 定义图表数据

接下来,我们来看看两个的区别:
一、 Plotly Express 来定义图表数据,当前的经纬度数据是手动配置的

--snip--
	x=lons,
    y=lats,
    labels={'x': '经度', 'y': '纬度'},
--snip--

二、pandas 定义图表数据
在这种方式中,所有有关数据的信息都以键值对的形式放在一个字典中。

import pandas as pd

data = pd.DataFrame(
    data=zip(lons, lats, titles, mags), columns=
    		['经度', '纬度', '位置', '震级']
)
data.head()

2.3.2 定制标记的尺寸、添加颜色

上文我们只是简单的在散点图显示在哪发生了地震,但没有指出震级,接下来就是要实现这个,定制标记的颜色让可视化图变得生动

--snip--
fig = px.scatter(
    data,
    x='经度',
    y='纬度',
    range_x=[-200,200],
    range_y=[-200,200],
    width=800,
    height=800,
    title='全球地震散点图',
    
# 新加入的大小以及颜色
    size='震级',
    size_max=10,    # 标记尺寸默认是20像素
    color='震级'	#默认的视觉映射图例渐变色是从小-蓝-红-黄-大
--snip--
)

可视化图如下:有了颜色渐变,以及标记点的大小区别,这样的可视化图能将关键信息显示的一目了然
CSV以及JSON格式的数据可视化_第5张图片

2.3.3 添加鼠标指向时显示的文本(地震位置)

在之前我们用 pandas 配置了 titles:'位置 '
接下来,我们用一句简单的代码实现这个功能

-snip--
	hover_name='位置'
--snip--

可视化图如下:添加了位置,这样我们就将大致的地震信息整合在可视化图上了
CSV以及JSON格式的数据可视化_第6张图片

你可能感兴趣的:(python,数据可视化)