代碼主要完成了從 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小時內與您取得聯系。