动态数据可视化:python生成折线赛车动画
代码解析
代码主要完成了从 SQLite 数据库读取数据,然后利用 Matplotlib 库创建一个动态的折线赛车图。以下是代码的主要结构和功能点:
-
库导入部分:
- 导入了 numpy, pandas, sqlite3, matplotlib 等库和函数。
-
设置 FFmpeg 路径:
- 用于动画视频的生成。
-
读取数据函数
read_data_from_db
:- 连接 SQLite 数据库,读取指定表的数据,并对数据进行处理,包括重命名列名,舍入数据和设置索引。
-
生成线性赛车图动画函数
line_chart_race
:- 该函数具有多个参数,包括数据库表名、日期列名称、输出文件名、图表标题、图表尺寸、DPI 和动画帧持续时间。
- 在函数内部,它首先读取数据,然后使用 matplotlib 创建一个动画对象,该对象在每个帧上调用
plot_frame
函数来绘制折线图。 - 最后,如果提供了文件名,它将动画保存为 MP4 文件,否则,它将尝试在 Jupyter Notebook 中以交互方式显示动画。
-
主函数部分:
- 调用
line_chart_race
函数来生成并保存动画。
- 调用
import numpy as np
import pandas as pd
import sqlite3
import matplotlib as mpl
from matplotlib import pyplot as plt
import matplotlib.animation as animation
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
mpl.rcParams['animation.ffmpeg_path'] = r"D:\RJ\ffmpeg-5.1.2-essentials_build\bin\ffmpeg.exe" # 请替换为你的 ffmpeg 的路径
# 读取数据,并对其进行处理,参数为数据库的表
def read_data_from_db(table_name, column_name=None):
# 连接到数据库
conn = sqlite3.connect(r'D:\wenjian\python\smart\data\req_data.db')
# 读取数据表
query = f"SELECT * FROM {table_name}"
dfdata = pd.read_sql_query(query, conn)
# 关闭数据库连接
conn.close()
dfdata = dfdata.rename({column_name: "date"}, axis=1)
# 对数据进行舍入
for col in dfdata.columns:
if col != "date":
dfdata.loc[:, col] = np.round(dfdata.loc[:, col], 3)
# 设置索引
dfdata.set_index("date")
return dfdata
# 生成线性赛车图动画
def line_chart_race(table_name, column_name=None, filename=None, title="", figsize=(8, 4.5), dpi=300, duration=0.5):
"""
参数:
table_name: 读取数据库(r'D:\wenjian\python\smart\data\req_data.db'的表名
column_name: 作为date的列名
filename: 输出文件的名称,如果提供,将保存为MP4文件,否则在Jupyter Notebook中以交互方式显示
title: 图表的标题
figsize: 图表的尺寸,以英寸为单位,格式为 (宽度, 高度)
dpi: 图表的像素密度,每英寸的点数
duration: 动画中每个帧的持续时间,以秒为单位
"""
# 设置中文显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 用黑体显示中文
# 颜色映射列表
cmap = ['#2E91E5', '#1CA71C', '#DA16FF', '#B68100', '#EB663B', '#00A08B', '#FC0080', '#6C7C32', '#862A16', '#620042', '#DA60CA', '#0D2A63'] * 100
mpl.rcParams['animation.writer'] = 'ffmpeg' # 更改为 'ffmpeg' 或 'avconv'
mpl.rcParams['animation.embed_limit'] = 200 # 设置为较大的值,例如100MB
df = read_data_from_db(table_name, column_name)
assert "date" in df.columns, "df应该有一个名为date的列!"
assert filename is None or filename.endswith(".mp4"), "文件名应该以*.mp4结尾!" # 更改为 '*.mp4'
fig, ax = plt.subplots(figsize=figsize, dpi=dpi) # 在函数内部定义 fig 和 ax
ax.set_facecolor("0.9") # 设置坐标轴背景颜色的代码,0.9为灰色
# 调整spines(图表的边框显示),False为不显示
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["bottom"].set_visible(False)
def plot_frame(date):
# 根据日期筛选数据
dfdata = df.loc[df["date"] <= date, :]
dfdata.index = dfdata["date"]
idx = range(len(dfdata))
ax.clear()
cols = [name for name in dfdata.columns if name != "date"]
for i, col in enumerate(cols):
# 绘制数据曲线
ax.plot(idx, dfdata[col], color=cmap[i], lw=2)
px, py = idx[-1], dfdata[col].iloc[-1]
# 绘制数据点
ax.scatter(px, py, color=cmap[i], edgecolor="black",
s=80, lw=2.5, zorder=4)
# 添加数据点注释
ax.annotate(col + ":\n" + str(py), xy=(px, py), xycoords="data",
xytext=(10, 2), fontweight="bold", color=cmap[i], textcoords="offset points")
# 根据当前显示的数据调整x轴和y轴范围
xlim = (0, px + 0.15 * (px - 0) + 0.1) # 调整x轴最大值,使数据点位于左三分之二的位置,并添加一个小的偏移量
ax.set_xlim(xmin=xlim[0], xmax=xlim[1])
values = dfdata[[x for x in dfdata.columns if x != "date"]].values
ylim = (values.min(), values.max())
ax.set_ylim(ymin=ylim[0] - (ylim[1] - ylim[0]) / 10, ymax=ylim[1] + (ylim[1] - ylim[0]) / 10)
# 设置xticks
ticks_num = 12
delta = int(np.ceil(len(dfdata) / ticks_num))
ticks = list(range(0, len(dfdata), delta))
dates = dfdata["date"].tolist()
ticklabels = [dates[i] for i in ticks]
ax.set_xticks(ticks)
ax.set_xticklabels(ticklabels, rotation=45) # 旋转x轴标签
ax.tick_params(bottom=False, left=False, labelsize=8, direction="in", length=2)
# 添加辅助元素
s = dfdata["date"].iloc[-1]
ax.text(0.5, 0.2, s, va="center", ha="center", alpha=0.3, size=25, transform=ax.transAxes)
ax.grid(axis="x", color="white", lw=1, ls="-")
ax.set_title(title, color="black", fontsize=12)
line_animation = animation.FuncAnimation(fig, plot_frame, frames=df["date"], interval=int(duration * 1000))
if filename is None:
try:
from IPython.display import HTML
return HTML(line_animation.to_jshtml())
except ImportError:
pass
else:
line_animation.save(filename) # 保存为MP4
return filename
# 调取函数
if __name__ == '__main__':
# 生成线性赛车图动画,参数分别是数据库的表、作为date列名称、导出视频名称和格式、图片大小、分解率、加解码时间
line_chart_race('测试2', '年份', '测试.mp4', title="测试2", figsize=(8, 4.5), dpi=300, duration=0.2)
FFmpeg 的安装
-
下载 FFmpeg:
- 访问 FFmpeg 的官方下载页面:https://www.ffmpeg.org/download.html。
- 在页面上,你会看到不同系统的下载链接,选择 Windows 的链接。通常,你可能会被重定向到一个第三方下载页面,例如 Gyan.dev 或 BtbN。
- 选择适合你的系统的版本(例如,如果你的系统是 64 位的,选择 64 位版本),然后下载 zip 文件。
-
解压 FFmpeg:
- 找到你刚刚下载的 zip 文件,通常会在你的“下载”文件夹中。
- 右键点击 zip 文件,然后选择“解压缩”或“提取”到一个你想要的目录,例如
C:\Program Files\ffmpeg
。
-
添加 FFmpeg 到系统 PATH:
- 右键点击“此电脑”或“我的电脑”图标,然后选择“属性”。
- 点击“高级系统设置”。
- 点击“环境变量”按钮。
- 在“系统变量”区域,找到并选择“Path”变量,然后点击“编辑”。
- 在编辑窗口中,点击“新建”,然后输入你的 FFmpeg 的
bin
目录的路径,例如C:\Program Files\ffmpeg\bin
。 - 点击“确定”保存你的设置。
-
验证 FFmpeg 安装:
- 打开一个新的命令提示符或 PowerShell 窗口(关闭任何旧的窗口,以确保新的环境变量设置生效)。
- 输入
ffmpeg -version
,然后按 Enter。 - 如果 FFmpeg 已正确安装,你应该能看到 FFmpeg 的版本信息。
标题建议
- 数据动态展现:Python生成折线赛车图
- 实时追踪数据变化:Python折线赛车图实战
- 动态数据可视化:Python折线赛车图详解
- Python动画制作:折线赛车图的生成与应用
- 数据赛车:Python折线图动态展示技术
标签建议
- Python
- 数据可视化
- 动态图表
- Matplotlib
- 数据分析
- 动画制作
- 数据处理
版权声明:
作者:余汉波
链接:https://www.sanrenjz.com/2023/10/08/%e5%8a%a8%e6%80%81%e6%95%b0%e6%8d%ae%e5%8f%af%e8%a7%86%e5%8c%96%ef%bc%9apython%e7%94%9f%e6%88%90%e6%8a%98%e7%ba%bf%e8%b5%9b%e8%bd%a6%e5%8a%a8%e7%94%bb/
文章版权归作者所有,未经允许请勿转载。
THE END