「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Matplotlib プロットを高速化してパフォーマンスを向上させる方法?

Matplotlib プロットを高速化してパフォーマンスを向上させる方法?

2024 年 11 月 6 日に公開
ブラウズ:206

How to Speed Up Matplotlib Plotting to Enhance Performance?

Matplotlib はなぜ遅いですか?

Python プロット ライブラリを評価するときは、パフォーマンスを考慮することが重要です。広く使用されているライブラリである Matplotlib は動作が遅いように見える場合があり、高速化や代替オプションの検討について疑問が生じます。問題を深く掘り下げて、考えられる解決策を検討してみましょう。

提供された例では、複数のサブプロットとデータ更新を含むプロットを示しています。 Matplotlib を使用すると、このプロセスには軸の境界や目盛りラベルを含むすべての再描画が含まれるため、パフォーマンスが低下します。

ボトルネックを理解する

速度低下の原因となる 2 つの重要な要素:

  1. 過剰な再描画: Matplotlib の fig.canvas.draw() 関数は、更新が必要なのはごく一部の場合でも、Figure 全体を再描画します。
  2. 豊富な目盛りラベル: 多数の目盛りラベルとサブプロットは、描画プロセスに大きな負担をかける可能性があります。

ブリッティングによる最適化

これらのボトルネックに対処するには、ブリッティングの使用を検討してください。ブリッティングでは、Figure の特定の部分のみを更新し、レンダリング時間を短縮します。ただし、効率的な実装にはバックエンド固有のコードが必要であり、GUI ツールキット内に Matplotlib プロットを埋め込む必要がある場合があります。

GUI 中立ブリッティング

GUI 中立ブリッティングこの技術は、バックエンドの依存関係なしで妥当なパフォーマンスを提供できます:

  1. 背景のキャプチャ: アニメーションの前に、後で復元するために各サブプロットの背景をキャプチャします。
  2. 更新and Draw: フレームごとに、線のデータとアーティストを更新し、背景を復元し、更新された部分をブリッティングします。
  3. Avoid Redraw: Use fig.canvas.blit( fig.canvas.draw() の代わりに ax.bbox) を使用して必要な領域のみを更新します。

実装例:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)

styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
    return ax.plot(x, y, style, animated=True)[0]

lines = [plot(ax, style) for ax, style in zip(axes, styles)]

# Capture Background
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]

for i in xrange(1, 2000):
    for j, (line, ax, background) in enumerate(zip(lines, axes, backgrounds), start=1):
        fig.canvas.restore_region(background)
        line.set_ydata(np.sin(j*x   i/10.0))
        ax.draw_artist(line)
        fig.canvas.blit(ax.bbox)

アニメーション モジュール

最近の Matplotlib バージョンには、ブリッティングを簡素化するアニメーション モジュールが含まれています。

import matplotlib.pyplot as plt
import matplotlib.animation as animation

def animate(i):
    for j, line in enumerate(lines, start=1):
        line.set_ydata(np.sin(j*x   i/10.0))

ani = animation.FuncAnimation(fig, animate, xrange(1, 200), interval=0, blit=True)
リリースステートメント この記事は次の場所に転載されています: 1729342040 権利侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3