代码主要完成了从 SQLite 数据库读取数据,然后利用 Matplotlib 库创建一个动态的折线赛车图。以下是代码的主要结构和功能点:
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)
现代前端开发中,可视化设计器逐渐成为了一个重要的功能模块,广泛应用于图形编辑、流程图绘制等领域。特别是在处理复杂路径、折线和最优路径应用时,通过Konva这一强大的HTML5 2D绘图库,开发者能够迅速构建功能强大、界面美观的可视化设计器。本文将深入探讨如何使用Konva实现折线的绘制与最优路径的应用,为你的开发之旅提供实用指南。
Konva是一个用于在浏览器中绘制2D图形的JavaScript库,基于HTML5 Canvas技术。它具有以下特点:
首先,需要在你的项目中引入Konva库。可以通过npm进行安装:
npm install konva
创建一个基础的HTML页面,并添加一个用于绘图的容器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Konva Visualization</title>
<style>
#container {
width: 100%;
height: 100vh;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://cdn.jsdelivr.net/npm/konva@8.2.1/konva.min.js"></script>
<script src="script.js"></script>
</body>
</html>
在 script.js 文件中,初始化Konva舞台(Stage)和层(Layer)。
document.addEventListener('DOMContentLoaded', function () {
var stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
var layer = new Konva.Layer();
stage.add(layer);
});
折线由多个点构成,每个点用一个数组表示。假设我们要绘制一条从(50, 50)到(200, 200)的折线:
var points = [
{ x: 50, y: 50 },
{ x: 150, y: 150 },
{ x: 200, y: 50 }
];
使用Konva的Line对象绘制折线,并将其添加到层中。
var line = new Konva.Line({
points: points.flatMap(point => [point.x, point.y]),
stroke: 'red',
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.draw();
最优路径算法在诸如导航、物流等应用中至关重要。我们以Dijkstra算法为例,计算两个点之间的最优路径
定义图的节点和边。
var graph = {
A: { B: 1, C: 4 },
B: { A: 1, C: 2, D: 5 },
C: { A: 4, B: 2, D: 1 },
D: { B: 5, C: 1 }
};
实现一个简化版的Dijkstra算法来计算最优路径。
function dijkstra(graph, start, end) {
var distances = {};
var prev = {};
var unvisited = new Set(Object.keys(graph));
for (var node in graph) {
distances[node] = Infinity;
prev[node] = null;
}
distances[start] = 0;
while (unvisited.size > 0) {
var closestNode = Array.from(unvisited).reduce((nearest, node) => {
return distances[node] < distances[nearest] ? node : nearest;
});
unvisited.delete(closestNode);
if (closestNode === end) {
var path = [];
while (prev[closestNode]) {
path.unshift(closestNode);
closestNode = prev[closestNode];
}
return [start, ...path];
}
for (var neighbor in graph[closestNode]) {
var distance = distances[closestNode] + graph[closestNode][neighbor];
if (distance < distances[neighbor]) {
distances[neighbor] = distance;
prev[neighbor] = closestNode;
}
}
}
return [];
}
假设我们要计算A点到D点的最优路径:
var optimalPath = dijkstra(graph, 'A', 'D');
// 转换路径点为Konva可用的格式
var optimalPoints = optimalPath.map(point => {
switch (point) {
case 'A': return { x: 50, y: 50 };
case 'B': return { x: 150, y: 150 };
case 'C': return { x: 200, y: 50 };
case 'D': return { x: 300, y: 200 };
}
});
var optimalLine = new Konva.Line({
points: optimalPoints.flatMap(point => [point.x, point.y]),
stroke: 'blue',
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round',
dash: [10, 5] // 虚线效果
});
layer.add(optimalLine);
layer.draw();
通过Konva强大的绘图能力和简单易用的API,我们可以轻松实现强大的可视化设计器功能。无论是基础的折线绘制,还是复杂的最优路径计算,Konva都能够胜任。希望本文能帮你快速上手Konva,打造功能强大的可视化设计工具。
如果你在使用Konva的过程中有更多的心得或疑问,欢迎在评论区留言讨论。让我们共同学习,共同进步,探索前端开发的更多可能性!
学 设 计
教 学 内 容 | 折线图数据变化的实现 | |||
教 学 目 标 | 知识目标:了解数据在图形变化中的作用 能力目标:能够完成折线图数据修改的代码编写 素质目标:培养学生团结互助、热爱祖国的综合素质 | |||
重 点 | Echarts中折线图定义和使用 | |||
难 点 | 折线图数据修改效果的代码编写 | |||
教学方法 | 讲授法、任务驱动法、启发法 | |||
课堂教学进程 | 教学环节 | 教师活动 | 学生活动 | 设计理念 |
1、 课堂考勤、上节课知识点回顾、课后作用问题处理(10分钟) 2、 课堂导入:折线图效果的实现(5分钟) 3、 新课内容:使用电子课件和效果演示工具的使用(20分钟) 以练习案例的方式引导学生自己动手实现效果,感受代码编写(45分钟) 4、总结课堂内容,布置作业(5分钟) 5 | ||||
*请认真填写需求信息,我们会在24小时内与您取得联系。