Python绘制数据(三)
一、制作全球地震散点图
1、查看json数据
import json# 指定原始JSON文件路径(包含地震数据)
fileName = 'D:\\py_projects\\eq_data_1_day_m1.json'# 1. 读取原始JSON文件
with open(fileName) as f:# 使用json.load()将JSON文本解析为Python字典/列表# data变量将包含整个JSON文件的结构化数据data = json.load(f)# 2. 创建格式化后的可读JSON文件
readable_file = 'D:\\py_projects\\eq_data_1_day_m1_readable.json'
with open(readable_file, 'w') as f:# 使用json.dump()将Python数据结构转换回JSON文本# - indent=4: 设置缩进为4个空格,使JSON层级更清晰# - ensure_ascii=False: 确保非ASCII字符(如中文)能正确显示json.dump(data, f, indent=4, ensure_ascii=False)
eq_data_1_day_m1_readable.json文件的说明:
"type": "FeatureCollection","metadata": { #主要是文件的相关信息"generated": 1550361461000,"url": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_day.geojson", #文件的地址"title": "USGS Magnitude 1.0+ Earthquakes, Past Day", #文件的标题"status": 200, #状态"api": "1.7.0","count": 158 #过去24h发生的地震的次数},....{"type": "Feature","properties": { #和每次地震有关的信息"mag": 1.2, #震级"place": "11km NNE of North Nenana, Alaska", #地震发生的地点"time": 1550358909272, #时间"updated": 1550359211283,"tz": -540,"url": "https://earthquake.usgs.gov/earthquakes/eventpage/ak0192641ikq","detail": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/ak0192641ikq.geojson","felt": null,"cdi": null,"mmi": null,"alert": null,"status": "automatic","tsunami": 0,"sig": 22,"net": "ak","code": "0192641ikq","ids": ",ak0192641ikq,","sources": ",ak,","types": ",geoserve,origin,","nst": null,"dmin": null,"rms": 0.94,"gap": null,"magType": "ml","type": "earthquake","title": "M 1.2 - 11km NNE of North Nenana, Alaska"},"geometry": { #地震发生的位置"type": "Point","coordinates": [-148.9865, #经度64.6673, #维度0]},"id": "ak0192641ikq"},
2、提取地震数据
import json# 指定JSON文件路径,该文件包含地震数据
fileName = 'D:\\py_projects\\eq_data_1_day_m1_readable.json'# 打开并读取JSON文件内容
with open(fileName) as f:data = json.load(f)# 从JSON数据中提取所有地震信息,存储在列表中
all_eq_data = data['features']
print(len(all_eq_data)) #158 文件记录了158次地震# 初始化四个空列表,用于存储提取的地震数据
mags, title, lons, lats = [], [], [], []# 遍历所有地震数据,提取关键信息
for feature in all_eq_data:# 提取震级信息mags.append(feature['properties']['mag'])# 提取地震标题(包含地点等信息)title.append(feature['properties']['title'])# 提取经度坐标lons.append(feature['geometry']['coordinates'][0])# 提取纬度坐标lats.append(feature['geometry']['coordinates'][1])
3、绘制震级散点图
import json
import plotly.express as px # 导入Plotly Express库用于数据可视化# 指定JSON文件路径,该文件包含地震数据
fileName = 'D:\\py_projects\\eq_data_1_day_m1_readable.json'# 打开并读取JSON文件内容
with open(fileName) as f:data = json.load(f)# 从JSON数据中提取所有地震信息,存储在列表中
# 'features'键包含了所有地震事件的详细信息
all_eq_data = data['features']
print(len(all_eq_data)) # 输出地震记录数量,此处为158条# 初始化四个空列表,用于存储提取的地震数据
mags, title, lons, lats = [], [], [], []# 遍历所有地震数据,提取关键信息
for feature in all_eq_data:# 提取震级信息(Magnitude)mags.append(feature['properties']['mag'])# 提取地震标题(包含地点、时间等信息)title.append(feature['properties']['title'])# 提取经度坐标(Longitude)lons.append(feature['geometry']['coordinates'][0])# 提取纬度坐标(Latitude)lats.append(feature['geometry']['coordinates'][1])# 使用Plotly Express创建散点图
# x轴为经度,y轴为纬度,展示全球地震分布
fig = px.scatter(x=lons,y=lats,labels={'x': 'longitude', 'y': 'latitude'}, # 设置坐标轴标签range_x=[-180, 180], # 设置x轴范围(经度范围为-180到180度)range_y=[-90, 90], # 设置y轴范围(纬度范围为-90到90度)width=800, # 设置图表宽度height=800, # 设置图表高度title='scatter plot of global earthquakes' # 设置图表标题)# 将图表保存为HTML文件,支持交互式查看
fig.write_html('D:\\py_projects\\eq_data_1_day_m1_readable.html')# 在浏览器中显示图表
fig.show()
4、另一种指定数据的方式
import json
import plotly.express as px # 导入Plotly Express库用于数据可视化
import pandas as pd # 导入Pandas库用于数据处理和分析# 指定JSON文件路径,该文件包含地震数据
fileName = 'D:\\py_projects\\eq_data_1_day_m1_readable.json'# 打开并读取JSON文件内容
with open(fileName) as f:data = json.load(f)# 从JSON数据中提取所有地震信息,存储在列表中
# 'features'键包含了所有地震事件的详细信息
all_eq_data = data['features']
print(len(all_eq_data)) # 输出地震记录数量,此处为158条# 初始化四个空列表,用于存储提取的地震数据
mags, title, lons, lats = [], [], [], []# 遍历所有地震数据,提取关键信息
for feature in all_eq_data:# 提取震级信息(Magnitude)mags.append(feature['properties']['mag'])# 提取地震标题(包含地点、时间等信息)title.append(feature['properties']['title'])# 提取经度坐标(Longitude)lons.append(feature['geometry']['coordinates'][0])# 提取纬度坐标(Latitude)lats.append(feature['geometry']['coordinates'][1])# 使用Pandas DataFrame存储地震数据,便于后续处理和可视化
# zip函数将多个列表按元素位置组合成元组,columns参数指定列名
data = pd.DataFrame(data=zip(mags, title, lons, lats), columns=['震级', '位置', '经度', '纬度']
)# 使用Plotly Express创建散点图
# x轴为经度,y轴为纬度,点的大小表示震级
fig = px.scatter(data, # 指定数据源为Pandas DataFramex='经度', # 设置x轴为经度列y='纬度', # 设置y轴为纬度列range_x=[-180, 180], # 设置经度范围(地球经度范围为-180到180度)range_y=[-90, 90], # 设置纬度范围(地球纬度范围为-90到90度)width=800, # 设置图表宽度为800像素height=800, # 设置图表高度为800像素title='全球地震散点图', # 设置图表标题size='震级', # 使用震级列的值控制散点大小size_max=10, # 设置散点最大尺寸为10像素
)# 将图表保存为HTML文件,支持交互式查看(可缩放、悬停显示详情等)
fig.write_html('D:\\py_projects\\eq_data_1_day_m1_readable.html')# 在浏览器中显示图表
fig.show()
5、过程解析
一、数据读取:从文件中获取原始数据
with open(fileName) as f:data = json.load(f)
open(fileName)
:打开文件,就像我们打开一个 Word 文档查看内容。json.load(f)
:将 JSON 格式的文本转换为 Python 中的字典(data
是一个大字典),这样程序就能通过 “键值对” 提取信息了。
二、数据提取:从原始数据中筛选有用信息
JSON 文件中的数据是结构化的(类似 “套娃” 的字典和列表),需要根据其内部结构 “按图索骥”,提取我们需要的信息(震级、经纬度等)。
定位地震数据集合:
all_eq_data = data['features']
JSON 数据中,features
这个键对应的值是一个列表,里面每个元素都是一次地震的详细信息(每个元素也是一个字典)。循环提取关键信息:
遍历all_eq_data
列表中的每个地震信息(feature
),提取 4 类核心数据:- 震级:
feature['properties']['mag']
(properties
是存储属性信息的字典,mag
是 “震级” 的键) - 位置:
feature['properties']['title']
(title
存储了地震发生的地点描述,如 “XX 海域附近”) - 经度:
feature['geometry']['coordinates'][0]
(geometry
存储地理坐标,coordinates
是经纬度的列表,第 1 个元素是经度) - 纬度:
feature['geometry']['coordinates'][1]
(coordinates
列表的第 2 个元素是纬度)
- 震级:
存储提取的信息:
用 4 个列表(mags, title, lons, lats
)分别存储所有地震的震级、位置、经度、纬度,相当于 “分类整理数据”。
三、数据处理:将信息转换为可视化所需格式
可视化工具(如 Plotly)更擅长处理结构化数据(类似 Excel 表格),因此需要将分散的列表数据转换为 “表格” 形式。
data = pd.DataFrame(data=zip(mags, title, lons, lats), columns=['震级', '位置', '经度', '纬度']
)
zip(mags, title, lons, lats)
:将 4 个列表 “对齐打包”,比如第 1 次地震的震级、位置、经纬度会被打包成一组数据。pd.DataFrame(...)
:用 Pandas 创建一个 “表格”(DataFrame),列名分别为 “震级”“位置” 等,就像我们在 Excel 中整理数据一样。
四、数据可视化:用图表展示数据
fig = px.scatter(data, # 用上面创建的“表格”作为数据源x='经度', y='纬度', # x轴放经度,y轴放纬度(对应地球表面的位置)size='震级', # 点的大小由震级决定(震级越大,点越大)... # 其他设置(如坐标轴范围、图表大小等)
)
- 散点图的本质:每个点代表一次地震,点的位置由 “经度 + 纬度” 决定(对应地球上的具体地点),点的大小反映震级(直观区分地震强度)。
- 为什么用经纬度?:经度(-180° 到 180°)和纬度(-90° 到 90°)是地球表面的 “坐标系统”,就像平面上的 X、Y 坐标,能唯一确定一个位置。
五、结果输出:保存和展示图表
fig.write_html(...)
:将图表保存为 HTML 文件,方便后续打开查看(支持交互,比如鼠标悬停看详情)。fig.show()
:直接在浏览器中显示图表,即时查看效果
6、定制标记的颜色,为震级添加渐变色
color='震级'
fig = px.scatter(data,x='经度',y='纬度',range_x=[-180, 180], # 设置x轴范围(经度范围为-180到180度)range_y=[-90, 90], # 设置y轴范围(纬度范围为-90到90度)width=800, # 设置图表宽度height=800, # 设置图表高度title='全球地震散点图', # 设置图表标题size='震级',size_max=10,color='震级'
)
7、显示地震位置
hover_name='位置'
fig = px.scatter(data,x='经度',y='纬度',range_x=[-180, 180], # 设置x轴范围(经度范围为-180到180度)range_y=[-90, 90], # 设置y轴范围(纬度范围为-90到90度)width=800, # 设置图表宽度height=800, # 设置图表高度title='全球地震散点图', # 设置图表标题size='震级',size_max=10,color='震级',hover_name='位置'
)