前导:入门+工具:
【数据可视化】Pyecharts连接MySQL数据库进行绘图(全)
【数据可视化(一)】Pyecharts中如何使用MySQL数据库中的数据
柱状排序图,先看成果:
可以查看某一范围内的地区:
一、数据库数据格式
三列:日期、地区、温度
二、代码
(一)数据库连接与数据处理
这部分与我上一篇文章里面完全相同,这里不多解释,可以移步上篇文章
【数据可视化(三)】Pyecharts绘制日历热力图
import pymysql
import pandas as pd
import re
from pyecharts import options as opts
from pyecharts.charts import Bar, Tab
# 连接数据库
db = pymysql.connect(
host="localhost",
user="root",
password="root",
db="xiangmu",
charset="utf8",
)
# 查询数据
sql = "SELECT * FROM China_temp_1"
try:
cursor = db.cursor()
cursor.execute(sql)
result = cursor.fetchall()
except Exception as e:
db.rollback()
print("Error", e)
else:
db.commit()
print("Success")
# 关闭数据库连接
db.close()
# 创建 DataFrame
df = pd.DataFrame(result, columns=['date', 'spot', 'temp'])
# 定义日期转换函数
def convert_date(date_str):
match = re.match(r"(\d{4})年(\d{1,2})月(\d{1,2})日", date_str)
if match:
year, month, day = match.groups()
return f"{year}/{month}/{day}"
return date_str
# 应用日期转换函数
df['date'] = df['date'].apply(convert_date)
# 将日期列转换为 datetime 格式
df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d', errors='coerce')
# 清理 temp 列,确保其为数值类型
df['temp'] = pd.to_numeric(df['temp'], errors='coerce')
# 去除重复记录
df = df.drop_duplicates(subset=['date', 'spot'], keep='first')
# 按照日期排序
df = df.sort_values(by='date')
(二)计算每年温度平均值
图中有一条平均值的横线,这部分将它计算出来:
计算每年的数据
def calculate_yearly_avg(df, year):
yearly_data = df[df['date'].dt.year == year]
yearly_avg = yearly_data.groupby(['spot']).agg(
avg_temp=pd.NamedAgg(column='temp', aggfunc='mean')
).reset_index()
return yearly_avg.sort_values(by='avg_temp', ascending=False) # 按温度降序排序
这里如果要升序排序,将ascending值设为True即可:
(三)创建Tab(年份选择框),绘制柱状图(对应pyecharts中的Bar类)
因为之前用这个图的背景是黑色,所以这里的x轴标签我设为白色了,图中看不出,修改一下颜色即可。地区太多,x轴标签显示不下,可以使用标签旋转功能,这里的rotate是文字旋转的角度,效果如下:
axislabel_opts=opts.LabelOpts(color='#FFF', rotate=60) # 旋转 x 轴标签
# 创建 Tab 实例
tab = Tab()
# 生成每年的数据并添加到 Tab 中
for year in [2020, 2021, 2022, 2023]:
yearly_avg_data = calculate_yearly_avg(df, year)
# 计算每年的全国平均温度
overall_avg_temp = yearly_avg_data['avg_temp'].mean()
bar = (
Bar(init_opts=opts.InitOpts(bg_color='rgba(0,0,0,0)',width='2000px',height='600px'))
.add_xaxis(yearly_avg_data['spot'].tolist())
.add_yaxis(
series_name=f"{year} 年平均温度",
y_axis=yearly_avg_data['avg_temp'].tolist(),
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title=f"{year} 年中国各地区年平均温度"),
xaxis_opts=opts.AxisOpts(
name="地区",
axislabel_opts=opts.LabelOpts(color='#FFF', rotate=60) # 旋转 x 轴标签
),
yaxis_opts=opts.AxisOpts(name="平均温度 (°C)"),
visualmap_opts=opts.VisualMapOpts(
orient="horizontal",
pos_left="center",
min_=yearly_avg_data['avg_temp'].min(),
max_=yearly_avg_data['avg_temp'].max(),
range_text=["高温", "低温"],
dimension=1,
range_color=["#D7DA8B", "#E15457"],
),
)
.set_series_opts(
bar_width="30%",
markline_opts=opts.MarkLineOpts(
data=[
{"type": "line", "name": f"{year} 年全国平均温度", "yAxis": overall_avg_temp}
],
label_opts=opts.LabelOpts(formatter="{b}: {c}", position="end"),
),
)
)
# 将 Bar 图添加到 Tab 中
tab.add(bar, f"{year}")
(四)渲染图表
# 渲染为 HTML 文件
tab.render("index.html")
三、运行结果
四、源代码
import pymysql
import pandas as pd
import re
from pyecharts import options as opts
from pyecharts.charts import Bar, Tab
# 连接数据库
db = pymysql.connect(
host="localhost",
user="root",
password="root",
db="xiangmu",
charset="utf8",
)
# 查询数据
sql = "SELECT * FROM China_temp_1"
try:
cursor = db.cursor()
cursor.execute(sql)
result = cursor.fetchall()
except Exception as e:
db.rollback()
print("Error", e)
else:
db.commit()
print("Success")
# 关闭数据库连接
db.close()
# 创建 DataFrame
df = pd.DataFrame(result, columns=['date', 'spot', 'temp'])
# 定义日期转换函数
def convert_date(date_str):
match = re.match(r"(\d{4})年(\d{1,2})月(\d{1,2})日", date_str)
if match:
year, month, day = match.groups()
return f"{year}/{month}/{day}"
return date_str
# 应用日期转换函数
df['date'] = df['date'].apply(convert_date)
# 将日期列转换为 datetime 格式
df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d', errors='coerce')
# 清理 temp 列,确保其为数值类型
df['temp'] = pd.to_numeric(df['temp'], errors='coerce')
# 去除重复记录
df = df.drop_duplicates(subset=['date', 'spot'], keep='first')
# 按照日期排序
df = df.sort_values(by='date')
# 计算每年的数据
def calculate_yearly_avg(df, year):
yearly_data = df[df['date'].dt.year == year]
yearly_avg = yearly_data.groupby(['spot']).agg(
avg_temp=pd.NamedAgg(column='temp', aggfunc='mean')
).reset_index()
return yearly_avg.sort_values(by='avg_temp', ascending=True) # 按温度降序排序
# 创建 Tab 实例
tab = Tab()
# 生成每年的数据并添加到 Tab 中
for year in [2020, 2021, 2022, 2023]:
yearly_avg_data = calculate_yearly_avg(df, year)
# 计算每年的全国平均温度
overall_avg_temp = yearly_avg_data['avg_temp'].mean()
bar = (
Bar(init_opts=opts.InitOpts(bg_color='rgba(0,0,0,0)',width='2000px',height='600px'))
.add_xaxis(yearly_avg_data['spot'].tolist())
.add_yaxis(
series_name=f"{year} 年平均温度",
y_axis=yearly_avg_data['avg_temp'].tolist(),
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title=f"{year} 年中国各地区年平均温度"),
xaxis_opts=opts.AxisOpts(
name="地区",
axislabel_opts=opts.LabelOpts(color='#000', rotate=60) # 旋转 x 轴标签
),
yaxis_opts=opts.AxisOpts(name="平均温度 (°C)"),
visualmap_opts=opts.VisualMapOpts(
orient="horizontal",
pos_left="center",
min_=yearly_avg_data['avg_temp'].min(),
max_=yearly_avg_data['avg_temp'].max(),
range_text=["高温", "低温"],
dimension=1,
range_color=["#D7DA8B", "#E15457"],
),
)
.set_series_opts(
bar_width="30%",
markline_opts=opts.MarkLineOpts(
data=[
{"type": "line", "name": f"{year} 年全国平均温度", "yAxis": overall_avg_temp}
],
label_opts=opts.LabelOpts(formatter="{b}: {c}", position="end"),
),
)
)
# 将 Bar 图添加到 Tab 中
tab.add(bar, f"{year}")
# 渲染为 HTML 文件
tab.render("index.html")