【数据可视化(四)】Pyecharts绘制数据排序柱状图

 前导:入门+工具:

【数据可视化】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")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值