」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 pyplot 進行即時繪圖

使用 pyplot 進行即時繪圖

發佈於2024-11-08
瀏覽:595

Real-time plotting with pyplot

我想繪製一些從簡單的投票應用程式產生的資料的圖表。我過去曾對 pyplot 進行過修改,但我沒有嘗試從頭開始創建任何東西。幸運的是,它非常流行,並且在 StackOverflow 和其他地方可以找到大量範例。

我進行了搜索,並從這個與隨時間更新圖表相關的答案開始。

import matplotlib.pyplot as plt
import numpy as np

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
    line1.set_ydata(np.sin(x   phase))
    fig.canvas.draw()
    fig.canvas.flush_events()

此程式碼動畫改變正弦波的相位。

前兩行導入我想要使用的函式庫:matplotlib.pyplot 進行繪圖和處理 GUI。

ion() 方法,如果我理解的話(儘管我可能不理解),使 pyplot 驅動 GUI。您也可以在 tkinter 程式中使用它,或使用它來產生靜態圖像,但在我們的範例中,讓它為我們處理圖形的 GUI 是有意義的。 (這就是稍後調用的flush_events()正在做的事情:允許與圖形視窗進行互動。)

此範例使用 numpy 方法 linspace() 建立 x 值。它傳回一個 numpy 數組,這是一個奇特的 Python 列表。

使用 np.sin 而不是 math.sin 的原因是廣播。這是將函數應用於列表中每個項目的 numpy 術語。事實上,我發現使用 map:
無需 numpy 也可以實現相同的事情

map(lambda n: math.sin(n), x)

但是numpy廣播使用起來方便簡單。

現在是 pyplot 設定。首先,建立一個新的「圖形」(圖)。在此圖中,新增一個子圖(ax)-可能有很多。 111 有相當深奧的解釋,「建立一個 1x1 網格,並將這個子圖放在第一個單元格中。」

在此子圖(或軸集)中,使用傳遞的 x 和 y 值繪製一條線。 (點以直線連接並連續繪製。)「r-」是指定紅色實線的簡寫方式。我們可以指定多行,因此plot()傳回一個元組;上面的程式碼使用元組解包來提取我們想要的一個值。

這是一個好的開始,但我需要隨著時間的推移延長 x 軸。如有必要,此程式碼也不會更新 y 軸的邊界 - 它被鎖定到為第一個圖計算的任何邊界。更多的搜尋讓我找到了這個答案。引用他們的話:

您將需要更新軸的 dataLim,然後根據 dataLim 更新軸的 viewLim。適當的方法是axes.relim()和ax.autoscale_view()方法。

當然,聽起來不錯。根據他們的範例,我創建了一個在 x 和 y 上都成長的演示圖。

import matplotlib.pyplot as plt
import numpy as np
from threading import Thread
from time import sleep

x = list(map(lambda x: x / 10, range(-100, 100)))
x_next_max = 100
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1 = ax.plot(x, y, 'r-')[0] # Returns a tuple of line objects

growth = 0

while True:
    x.append(x_next_max / 10)
    x_next_max  = 1
    line1.set_xdata(x)
    line1.set_ydata(np.sin(x)   np.sin(np.divide(x, 100))   np.divide(x, 100))
    ax.relim()
    ax.autoscale()
    fig.canvas.draw()
    fig.canvas.flush_events()

    sleep(0.1)

現在我已經有所進展了。但是,這是一個阻塞循環,我需要偶爾更新我的資料。如果我有多個線程,我就必須擔心更新變數時的線程安全性問題。在這種情況下,我可以偷懶,因為我知道該變數僅每 5 分鐘更新一次(或無論輪詢函數運行多久);變數在程式碼行中間不存在被覆蓋的危險。

import matplotlib.pyplot as plt
import numpy as np
from threading import Timer
from time import sleep

x = list(map(lambda x: x / 10, range(-100, 100)))
x_next_max = 100
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1 = ax.plot(x, y, 'r-')[0] # Plot returns a tuple of line objects

growth = 0
new_x = None

dT = 1

def grow():
    global new_x, x_next_max
    while True:
        new_x = x   [x_next_max / 10]
        x_next_max  = 1
        sleep(dT) # grow every dT seconds

t = Thread(target=grow)
t.start()

while True:

    if new_x:
        x = new_x
        new_x = None
        line1.set_xdata(x)
        line1.set_ydata(np.sin(x)   np.sin(np.divide(x, 100))   np.divide(x, 100))
        ax.relim()
        ax.autoscale()
        fig.canvas.draw()

    fig.canvas.flush_events()

    sleep(0.1)

只有當成長執行緒為 new_x 賦值時,此圖才會更新。請注意,flush_events() 呼叫位於「if」語句之外,因此它被頻繁地呼叫。

版本聲明 本文轉載於:https://dev.to/paxfeline/real-time-plotting-with-pyplot-2b3g?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何以程式設計方式為 LinearLayout 中的按鈕新增邊距?
    如何以程式設計方式為 LinearLayout 中的按鈕新增邊距?
    LinearLayout 中的動態邊距LinearLayout 中的動態邊距在Android 開發中,佈局在組織和顯示使用者介面元素方面發揮著至關重要的作用。佈局的一個常見要求是能夠指定元素之間的邊距。雖然 XML 提供了一種直觀的方式來定義邊距,但開發人員可能需要以程式設計方式建立佈局以確保靈活性...
    程式設計 發佈於2024-11-08
  • 如何使用 PowerMock 和 Mockito 有效模擬私有方法?
    如何使用 PowerMock 和 Mockito 有效模擬私有方法?
    使用PowerMock 模擬私有方法的替代解決方案儘管最初提出的使用PowerMock 的解決方案遇到了困難,但事實證明,另一種方法是成功的。使用 Mockito 和 PowerMock 的組合,可以有效地模擬私有方法。 如提供的程式碼片段所示,類別 CodeWithPrivateMethod 擁有...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中將列式資料結構轉換為基於行的格式?
    如何在 PHP 中將列式資料結構轉換為基於行的格式?
    將多維列式資料重新排序為基於行的結構給定一個具有面向列資料的關聯數組,任務是將其轉置為由行組成的多維數組。原始數組中的資料按列排列,目標是將同一列的值合併到行中。 原始陣列:$where = [ 'id' => [ 12, 13, 14 ...
    程式設計 發佈於2024-11-08
  • Next.JS 或 Nuxt.JS 哪個最好
    Next.JS 或 Nuxt.JS 哪個最好
    The ability to build scalable and seamless web applications quickly is the dream of every web developer. As a result, the importance of frameworks in ...
    程式設計 發佈於2024-11-08
  • 了解 RESTful API 和 Web 服務:主要差異和用例
    了解 RESTful API 和 Web 服務:主要差異和用例
    在現代軟體開發領域,RESTful API 和 Web 服務都是實現不同系統之間無縫通訊的基礎。雖然這些術語經常互換使用,但它們代表具有獨特特徵和用例的不同概念。對於旨在建立高效、可互通且可擴展的應用程式的開發人員來說,掌握 RESTful API 和 Web 服務 之間的差異至關重要。在本節中,我...
    程式設計 發佈於2024-11-08
  • React 應用程式的基本設計模式:升級您的組件遊戲
    React 應用程式的基本設計模式:升級您的組件遊戲
    如果您已经进入 React 世界一段时间,您可能听说过“这只是 JavaScript”这句话。虽然这是事实,但这并不意味着我们不能从一些经过验证的模式中受益,使我们的 React 应用程序更易于维护、可重用并且使用起来更加愉快。让我们深入研究一些基本的设计模式,这些模式可以让你的 React 组件从...
    程式設計 發佈於2024-11-08
  • 使用 PHP 建立 API 和 Web 服務
    使用 PHP 建立 API 和 Web 服務
    使用 PHP 建立 API 和 Web 服務涉及以下步驟:建立 PHP 環境,安裝 PHP、Apache 伺服器和 mod_php 模組。建立 API,編寫 PHP 腳本處理請求並回傳回應。建立 Web 服務,使用 PHP 框架或純 PHP 來建立伺服器。實戰案例:建立用戶註冊 API,處理 POS...
    程式設計 發佈於2024-11-08
  • Restful 路由 - Flask API 範例
    Restful 路由 - Flask API 範例
    Restful 路由致力於使所有不同應用程式的路由保持一致。 REST 是表述性狀態轉移。它以一致的、人類可讀的、機器可讀的方式使用 HTTP。 標準是 GET、POST、PATCH、PUT 和 DELETE。 下面將給出 Flask API 資料庫中的幾個靜態路由的範例,用於從前端獲取/向前端...
    程式設計 發佈於2024-11-08
  • ## 如何在沒有反向引用的情況下匹配 Go 正規表示式中的重複字元?
    ## 如何在沒有反向引用的情況下匹配 Go 正規表示式中的重複字元?
    在Go 的正規表示式中符合重複字元在Go 的正規表示式中,符合重複字元可能是一個挑戰,因為不支援反向引用。這可能會令人沮喪,特別是當您需要執行複雜的模式匹配任務時。 要解決此限制,有兩種可能的解決方案:使用替代正則表達式庫:一種選擇是使用支援反向引用的第三方正規表示式庫。一個流行的選擇是“glenn...
    程式設計 發佈於2024-11-08
  • 如何找到 Pandas DataFrame 中多列的最大值?
    如何找到 Pandas DataFrame 中多列的最大值?
    查找 Pandas DataFrames 中多列的最大值在資料分析中,查找多列的最大值是一項常見任務。在Python中,Pandas函式庫提供了執行此類操作的有效方法。 問題陳述:假設您有一個包含A列和B列的DataFrame,並且您需要建立一個新列 C,其中每個值都是 A列中對應值的最大值,且B....
    程式設計 發佈於2024-11-08
  • 用 Java 建立一個不依賴任何依賴的 Web 伺服器
    用 Java 建立一個不依賴任何依賴的 Web 伺服器
    我幾個月來一直致力於一個業餘愛好項目,這是一個 MIT 許可的 API 網關,旨在獨立於任何特定供應商。老實說,我認為一切都很順利。隨著我的程式碼庫的成長,我看到了圍繞核心(即 HTTP 伺服器)進行改進的機會。將核心 HTTP 伺服器拆分為自己的微框架似乎是一個合乎邏輯的解決方案(也是一個很好的學...
    程式設計 發佈於2024-11-08
  • 建置 jargons.dev [# Fork 腳本
    建置 jargons.dev [# Fork 腳本
    这是我按照系统架构中所述编写的 4 个脚本中的第一个。感觉很抽气!这是朝着创建“wiki”体验方向迈出的一步,无需与 GitHub UI 交互即可为开源做出贡献?. 这些脚本是什么? 这些 js 文件包含一些相关的可重用函数,特别是用于与 GitHub API 交互;它们要么在同一脚...
    程式設計 發佈於2024-11-08
  • 使用 Java + Quarkus + Langchain 建立可靠的 AI 代理程式 - 部分 AI 即服務
    使用 Java + Quarkus + Langchain 建立可靠的 AI 代理程式 - 部分 AI 即服務
    Autores @herbertbeckman - LinkedIn @rndtavares - LinkedIn Partes do artigo Agente de IA confiável em prod com Java Quarkus Langch...
    程式設計 發佈於2024-11-08
  • 如何使用 Python 的 smtplib 向多個收件者發送電子郵件?
    如何使用 Python 的 smtplib 向多個收件者發送電子郵件?
    如何使用Python 的smtplib 向多個收件者發送電子郵件利用smtplib.sendmail 將電子郵件傳輸給多個收郵件件人可能具有挑戰性。若要將郵件成功傳送至多個位址,請遵循以下準則:使用逗號分隔的電子郵件地址設定標頭:在電子郵件標頭中(msg[" To"]),使用一串...
    程式設計 發佈於2024-11-08
  • 如何透過您的 Web 應用程式獲利:無需立即批准網域名稱。
    如何透過您的 Web 應用程式獲利:無需立即批准網域名稱。
    網路貨幣化即使不是不必要的困難,也是乏味的。 等待Google的批准——如果有的話;直到今天我還在等待。 將網域作為您的專案貨幣化的看門人。 如果不是把關問題,那就是Google瘋狂削減了! 我剛開始我的獲利之旅,遇到了所有這些壓力,促使我尋找解決所有這些煩惱的替代方案。 解決方案必須: ...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3