【数据可视化(三)】Pyecharts绘制日历热力图

前导:入门+工具:

【数据可视化】Pyecharts连接MySQL数据库进行绘图(全) 
【数据可视化(一)】Pyecharts中如何使用MySQL数据库中的数据 

 日历热力图的绘制,先看成果:

程序中连接数据库中不同的表,可以实现一年中温度的可视化。

一、数据库数据格式

三列:日期、地点、温度

二、代码

(一)导入库

pymysql--用于连接和操作 MySQL 数据库;

pandas--用于数据处理和分析;

re--正则表达式库,用于处理和转换日期格式。

import pymysql
import pandas as pd
import re
import pyecharts.options as opts
from pyecharts.charts import Calendar, Tab
from pyecharts.globals import ThemeType

(二)数据库连接与查询

使用 pymysql.connect 连接到 MySQL 数据库,指定主机、用户名、密码、数据库名和字符集。

我们选择五个地区来展示。

# 连接数据库
db = pymysql.connect(
    host="localhost",
    user="root",
    password="root",
    db="xiangmu",
    charset="utf8",
)
# 查询数据
sql = "SELECT * FROM China_temp_1 WHERE spot IN ('天津市', '广东省', '西藏自治区', '黑龙江省', '浙江省')"
try:
    cursor = db.cursor()
    cursor.execute(sql)
    result = cursor.fetchall()
except Exception as e:
    db.rollback()
    print("Error", e)
else:
    db.commit()
    print("Success")

(三)数据处理

创建DataFrame,在上篇文章提到过:

# 创建 DataFrame
df = pd.DataFrame(result, columns=['date', 'spot', 'temp'])

因为数据库中的数据来源不同,日期格式可能不同,所以检查并修改,convert_date 函数:使用正则表达式检查和转换日期格式,从“2020年1月1日”转换为“2020/1/1”:

# 定义日期转换函数
def convert_date(date_str):
    # 检查日期格式是否为“2020年1月1日”
    match = re.match(r"(\d{4})年(\d{1,2})月(\d{1,2})日", date_str)
    if match:
        year, month, day = match.groups()
        # 转换为“2020/1/1”格式
        return f"{year}/{month}/{day}"
    return date_str
# 应用日期转换函数
df['date'] = df['date'].apply(convert_date)

 将日期列转换为 datetime 格式,以便进行时间序列分析,处理无法转换的日期为 NaT(缺失值),后续一并去除:

# 将日期列转换为 datetime 格式
df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d', errors='coerce')

 去除重复记录,保留每个日期和地点的第一次出现的记录:

# 去除重复记录
df = df.drop_duplicates(subset=['date', 'spot'], keep='first')

 按照日期对 DataFrame 进行排序,以便正确展示时间序列数据:

# 按照日期排序
df = df.sort_values(by='date')

(四)创建和配置图表

Tab对象即最上方的城市选择框,可以点击它们切换不同城市数据。

创建一个 Tab 对象,用于将多个图表合并到一个页面中;定义一个地区列表,用于生成图表:

# 创建 Tab 对象
tab = Tab()
# 获取需要展示的地区列表
regions = ['天津市', '广东省', '西藏自治区', '黑龙江省', '浙江省']

遍历每个地区,过滤出对应地区和年份的数据;将数据转换为 pyecharts 日历图表所需的格式,日期和温度以列表形式存储:

# 遍历每个地区,创建对应的 Calendar 图表
for region in regions:
    # 过滤出特定地区的数据
    df_region = df[df['spot'] == region]
    # 过滤出 2022 年的数据
    df_2022 = df_region[df_region['date'].dt.year == 2022]
    # 转换 DataFrame 为 Calendar 图表所需的数据格式
    data = [
        [str(row['date'].date()), row['temp']]
        for _, row in df_2022.iterrows()
    ]

 最后,为每个地区创建一个 Calendar 图表(即日历图),并设置其初始选项、添加数据、设置全局选项如标题和视觉映射(颜色区间);将生成的 Calendar 图表添加到 Tab 对象中:

    # 创建 Calendar 图表
    calendar = (
        Calendar(init_opts=opts.InitOpts(
            bg_color='rgba(0,0,0,0)',
            width='2000px',
            height='600px',
            theme=ThemeType.PURPLE_PASSION,
            )
        )
        .add(
            series_name=f"{region} Temperature Data 2022",
            yaxis_data=data,
            calendar_opts=opts.CalendarOpts(
                pos_top="120",
                pos_left="30",
                pos_right="30",
                range_="2022",
                yearlabel_opts=opts.CalendarYearLabelOpts(is_show=False),
            ),
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(pos_top="30", pos_left="center", title=f"{region} Temperature Data 2022"),
            visualmap_opts=opts.VisualMapOpts(
                is_piecewise=True,
                pieces=[
                    {"max": 80, "min": 35, "label": ">35℃", "color": "#E00501"},
                    {"max": 34.99, "min": 32, "label": "32-35℃", "color": "#FA5702"},
                    {"max": 31.99, "min": 28, "label": "28-32℃", "color": "#FA9682"},
                    {"max": 27.99, "min": 24, "label": "24-28℃", "color": "#FFCCA1"},
                    {"max": 23.99, "min": 20, "label": "20-24℃", "color": "#FFF3C3"},
                    {"max": 19.99, "min": 16, "label": "16-20℃", "color": "#BAFB95"},
                    {"max": 15.99, "min": 12, "label": "12~16℃", "color": "#CEFFCE"},
                    {"max": 11.99, "min": 8, "label": "8~12℃", "color": "#D0FCFF"},
                    {"max": 7.99, "min": 4, "label": "4~8℃", "color": "#AAE9F8"},
                    {"max": 3.99, "min": 0, "label": "0~4℃", "color": "#85D0FF"},
                    {"max": -0.01, "min": -4, "label": "-4~0℃", "color": "#3E9FEC"},
                    {"max": -4.01, "min": -10, "label": "-10~-4℃", "color": "#2373D2"},
                    {"max": -10.01, "min": -20, "label": "-20~-10℃", "color": "#1C5D9E"},
                    {"max": -20.01, "min": -50, "label": "<-20℃", "color": "#002F87"},
                ]
            ),
        )
    )
    # 将 Calendar 图表添加到 Tab 中
    tab.add(calendar, region)

(五)渲染图表

# 渲染为 HTML 文件
tab.render("index.html")

三、运行结果

四、源代码

import pymysql
import pandas as pd
import re
import pyecharts.options as opts
from pyecharts.charts import Calendar, Tab
from pyecharts.globals import ThemeType

# 连接数据库
db = pymysql.connect(
    host="localhost",
    user="root",
    password="root",
    db="xiangmu",
    charset="utf8",
)
# 查询数据
sql = "SELECT * FROM China_temp_1 WHERE spot IN ('天津市', '广东省', '西藏自治区', '黑龙江省', '浙江省')"
try:
    cursor = db.cursor()
    cursor.execute(sql)
    result = cursor.fetchall()
except Exception as e:
    db.rollback()
    print("Error", e)
else:
    db.commit()
    print("Success")
# 创建 DataFrame
df = pd.DataFrame(result, columns=['date', 'spot', 'temp'])
# 定义日期转换函数
def convert_date(date_str):
    # 检查日期格式是否为“2020年1月1日”
    match = re.match(r"(\d{4})年(\d{1,2})月(\d{1,2})日", date_str)
    if match:
        year, month, day = match.groups()
        # 转换为“2020/1/1”格式
        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')
# 去除重复记录
df = df.drop_duplicates(subset=['date', 'spot'], keep='first')
# 按照日期排序
df = df.sort_values(by='date')
# 创建 Tab 对象
tab = Tab()
# 获取需要展示的地区列表
regions = ['天津市', '广东省', '西藏自治区', '黑龙江省', '浙江省']
# 遍历每个地区,创建对应的 Calendar 图表
for region in regions:
    # 过滤出特定地区的数据
    df_region = df[df['spot'] == region]
    # 过滤出 2022 年的数据
    df_2022 = df_region[df_region['date'].dt.year == 2022]
    # 转换 DataFrame 为 Calendar 图表所需的数据格式
    data = [
        [str(row['date'].date()), row['temp']]
        for _, row in df_2022.iterrows()
    ]
    # 创建 Calendar 图表
    calendar = (
        Calendar(init_opts=opts.InitOpts(
            bg_color='rgba(0,0,0,0)',
            width='2000px',
            height='600px',
            theme=ThemeType.PURPLE_PASSION,
            )
        )
        .add(
            series_name=f"{region} Temperature Data 2022",
            yaxis_data=data,
            calendar_opts=opts.CalendarOpts(
                pos_top="120",
                pos_left="30",
                pos_right="30",
                range_="2022",
                yearlabel_opts=opts.CalendarYearLabelOpts(is_show=False),
            ),
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(pos_top="30", pos_left="center", title=f"{region} Temperature Data 2022"),
            visualmap_opts=opts.VisualMapOpts(
                is_piecewise=True,
                pieces=[
                    {"max": 80, "min": 35, "label": ">35℃", "color": "#E00501"},
                    {"max": 34.99, "min": 32, "label": "32-35℃", "color": "#FA5702"},
                    {"max": 31.99, "min": 28, "label": "28-32℃", "color": "#FA9682"},
                    {"max": 27.99, "min": 24, "label": "24-28℃", "color": "#FFCCA1"},
                    {"max": 23.99, "min": 20, "label": "20-24℃", "color": "#FFF3C3"},
                    {"max": 19.99, "min": 16, "label": "16-20℃", "color": "#BAFB95"},
                    {"max": 15.99, "min": 12, "label": "12~16℃", "color": "#CEFFCE"},
                    {"max": 11.99, "min": 8, "label": "8~12℃", "color": "#D0FCFF"},
                    {"max": 7.99, "min": 4, "label": "4~8℃", "color": "#AAE9F8"},
                    {"max": 3.99, "min": 0, "label": "0~4℃", "color": "#85D0FF"},
                    {"max": -0.01, "min": -4, "label": "-4~0℃", "color": "#3E9FEC"},
                    {"max": -4.01, "min": -10, "label": "-10~-4℃", "color": "#2373D2"},
                    {"max": -10.01, "min": -20, "label": "-20~-10℃", "color": "#1C5D9E"},
                    {"max": -20.01, "min": -50, "label": "<-20℃", "color": "#002F87"},
                ]
            ),
        )
    )
    # 将 Calendar 图表添加到 Tab 中
    tab.add(calendar, region)
# 渲染为 HTML 文件
tab.render("index.html")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值