整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          動態數據可視化:python生成折線賽車動畫

          碼解析

          代碼主要完成了從 SQLite 數據庫讀取數據,然后利用 Matplotlib 庫創建一個動態的折線賽車圖。以下是代碼的主要結構和功能點:

          1. 庫導入部分: 導入了 numpy, pandas, sqlite3, matplotlib 等庫和函數。
          2. 設置 FFmpeg 路徑: 用于動畫視頻的生成。
          3. 讀取數據函數 read_data_from_db: 連接 SQLite 數據庫,讀取指定表的數據,并對數據進行處理,包括重命名列名,舍入數據和設置索引。
          4. 生成線性賽車圖動畫函數 line_chart_race: 該函數具有多個參數,包括數據庫表名、日期列名稱、輸出文件名、圖表標題、圖表尺寸、DPI 和動畫幀持續時間。 在函數內部,它首先讀取數據,然后使用 matplotlib 創建一個動畫對象,該對象在每個幀上調用 plot_frame 函數來繪制折線圖。 最后,如果提供了文件名,它將動畫保存為 MP4 文件,否則,它將嘗試在 Jupyter Notebook 中以交互方式顯示動畫。
          5. 主函數部分: 調用 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 的安裝

          1. 下載 FFmpeg: 訪問 FFmpeg 的官方下載頁面。 在頁面上,你會看到不同系統的下載鏈接,選擇 Windows 的鏈接。通常,你可能會被重定向到一個第三方下載頁面,例如 Gyan.dev 或 BtbN。 選擇適合你的系統的版本(例如,如果你的系統是 64 位的,選擇 64 位版本),然后下載 zip 文件。
          2. 解壓 FFmpeg: 找到你剛剛下載的 zip 文件,通常會在你的“下載”文件夾中。 右鍵點擊 zip 文件,然后選擇“解壓縮”或“提取”到一個你想要的目錄,例如 C:\Program Files\ffmpeg。
          3. 添加 FFmpeg 到系統 PATH: 右鍵點擊“此電腦”或“我的電腦”圖標,然后選擇“屬性”。 點擊“高級系統設置”。 點擊“環境變量”按鈕。 在“系統變量”區域,找到并選擇“Path”變量,然后點擊“編輯”。 在編輯窗口中,點擊“新建”,然后輸入你的 FFmpeg 的 bin 目錄的路徑,例如 C:\Program Files\ffmpeg\bin。 點擊“確定”保存你的設置。
          4. 驗證 FFmpeg 安裝: 打開一個新的命令提示符或 PowerShell 窗口(關閉任何舊的窗口,以確保新的環境變量設置生效)。 輸入 ffmpeg -version,然后按 Enter。 如果 FFmpeg 已正確安裝,你應該能看到 FFmpeg 的版本信息。

          現代前端開發中,可視化設計器逐漸成為了一個重要的功能模塊,廣泛應用于圖形編輯、流程圖繪制等領域。特別是在處理復雜路徑、折線和最優路徑應用時,通過Konva這一強大的HTML5 2D繪圖庫,開發者能夠迅速構建功能強大、界面美觀的可視化設計器。本文將深入探討如何使用Konva實現折線的繪制與最優路徑的應用,為你的開發之旅提供實用指南。

          一、Konva簡介

          Konva是一個用于在瀏覽器中繪制2D圖形的JavaScript庫,基于HTML5 Canvas技術。它具有以下特點:

          • 高性能:能夠處理大量圖形對象。
          • 易用性:API簡單、易于上手。
          • 豐富的功能:支持圖形變換、事件處理、動畫等。

          二、項目初始化

          1.安裝Konva庫

          首先,需要在你的項目中引入Konva庫。可以通過npm進行安裝:

          npm install konva
          

          2.創建基本畫布

          創建一個基礎的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);
          });
          

          三、繪制折線

          1.定義折線數據

          折線由多個點構成,每個點用一個數組表示。假設我們要繪制一條從(50, 50)到(200, 200)的折線:

          var points = [
              { x: 50, y: 50 },
              { x: 150, y: 150 },
              { x: 200, y: 50 }
          ];
          

          2.創建并添加折線

          使用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算法為例,計算兩個點之間的最優路徑

          1.創建圖數據結構

          定義圖的節點和邊。

          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 }
          };
          

          2.Dijkstra算法實現

          實現一個簡化版的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 [];
          }
          

          3.可視化最優路徑

          假設我們要計算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();
          

          五、優化與擴展

          1. 用戶交互:可以添加拖拽和點擊事件,讓用戶可以動態創建和修改折線。
          2. 動畫效果:為折線添加動畫效果,使路徑繪制更加生動。
          3. 復雜路徑算法:根據需求,集成其他更加復雜的路徑算法,如A*算法等。

          結語

          通過Konva強大的繪圖能力和簡單易用的API,我們可以輕松實現強大的可視化設計器功能。無論是基礎的折線繪制,還是復雜的最優路徑計算,Konva都能夠勝任。希望本文能幫你快速上手Konva,打造功能強大的可視化設計工具。

          如果你在使用Konva的過程中有更多的心得或疑問,歡迎在評論區留言討論。讓我們共同學習,共同進步,探索前端開發的更多可能性!

          學 設 計

          教 學 內 容

          折線圖數據變化的實現

          教 學 目 標

          知識目標:了解數據在圖形變化中的作用

          能力目標:能夠完成折線圖數據修改的代碼編寫

          素質目標:培養學生團結互助、熱愛祖國的綜合素質

          重 點

          Echarts中折線圖定義和使用

          難 點

          折線圖數據修改效果的代碼編寫

          教學方法

          講授法、任務驅動法、啟發法

          課堂教學進程

          教學環節

          教師活動

          學生活動

          設計理念

          1、 課堂考勤、上節課知識點回顧、課后作用問題處理(10分鐘)

          2、 課堂導入:折線圖效果的實現(5分鐘)

          3、 新課內容:使用電子課件和效果演示工具的使用(20分鐘)

          以練習案例的方式引導學生自己動手實現效果,感受代碼編寫(45分鐘)

          4、總結課堂內容,布置作業(5分鐘)

          5


          主站蜘蛛池模板: 亚洲欧洲日韩国产一区二区三区| 免费无码一区二区三区蜜桃大| 亚洲国产综合无码一区| 亚洲国产欧美一区二区三区| 国产精品区一区二区三在线播放| 国产亚洲一区二区三区在线不卡 | 国产一区二区三区免费视频| 亚洲av成人一区二区三区观看在线 | 亚洲一区二区三区日本久久九 | 又紧又大又爽精品一区二区| 久久精品免费一区二区| 日韩成人无码一区二区三区 | 精品国产一区二区三区免费| 久久国产精品免费一区| 无码精品人妻一区二区三区人妻斩 | 国产在线一区二区在线视频| 肉色超薄丝袜脚交一区二区| 亚洲AV成人一区二区三区观看 | 3d动漫精品一区视频在线观看| AV鲁丝一区鲁丝二区鲁丝三区 | 一区二区三区四区免费视频| 夜夜添无码试看一区二区三区| 亚洲AV成人精品日韩一区18p| 免费av一区二区三区| 亚洲日韩国产精品第一页一区 | 精品无码综合一区二区三区| 99热门精品一区二区三区无码| 中文字幕在线看视频一区二区三区| 中文字幕无码一区二区免费| 国产丝袜美女一区二区三区| 国产一区二区电影| 农村乱人伦一区二区| bt7086福利一区国产| 精品亚洲福利一区二区| 男人的天堂精品国产一区| 无码精品一区二区三区在线| 亚洲国产视频一区| 日本精品无码一区二区三区久久久| 天堂va视频一区二区| 中文字幕VA一区二区三区| 亚洲AV福利天堂一区二区三|