|
|
matplotlib Usage Guide. |
H.Kamifuji . |
このチュートリアルでは、Matplotlib を使い始めるための基本的な使用パターンとベストプラクティスについて説明します。 |
matplotlib には広範なコードベースがあり、多くの新しいユーザーには脅威になる可能性があります。 しかし、matplotlib のほとんどは、かなり単純な概念的なフレームワークと、いくつかの重要な点についての知識で理解することができます。 プロットは、最も一般的な(例えば、「この2-Dアレイの輪郭を描く」)から最も特定の(例えば、「このスクリーンピクセル赤色を着色する」)までの範囲のレベルでアクションを必要とする。 プロットパッケージの目的は、必要なすべての制御、つまり、比較的高レベルのコマンドを使用して、可能な限り簡単にデータを視覚化するのを支援し、低レベルを使用できるようにすることです 必要に応じてレベルコマンドを実行します。 したがって、matplotlib のすべては階層構造になっています。 階層の最上部には、matplotlib.pyplot モジュールによって提供される matplotlib 「状態マシン環境」があります。 このレベルでは、単純な関数を使用して、現在の図の現在の軸にプロット要素(線、画像、テキストなど)を追加します。 注記階層内の次のレベルは、オブジェクト指向インタフェースの第1レベルであり、figureplot は Figure の作成などのいくつかの関数に対してのみ使用され、ユーザーはFigureオブジェクトと Axes オブジェクトを明示的に作成して追跡します。 このレベルでは、ユーザは pyplot を使用して図を作成し、その図を介して1つ以上の軸オブジェクトを作成することができます。 これらの軸オブジェクトは、ほとんどのプロットアクションに使用されます。 GUI アプリケーションに matplotlib プロットを埋め込むなどのために不可欠な、より多くの制御を行うには、pyplot レベルを完全に落として純粋にオブジェクト指向のアプローチを残してください。 # sphinx_gallery_thumbnail_number = 3 import matplotlib.pyplot as plt import numpy as np |
![]() |
全体の数字。 この図は、すべての子 Axes 、「特別な」アーティスト( title 、Figure の凡例など)、およびキャンバスの散在を追跡します。 (キャンバスについて心配する必要はありませんが、プロットを得るために描画を実際に行うオブジェクトは重要ですが、ユーザーにとっては見えなくなります)。 Figure は任意の数の Axes を持つことができますが、有用であるには少なくとも1つ必要です。 新しい図を作成する最も簡単な方法は pyplot です: # sphinx_gallery_thumbnail_number = 3 import matplotlib.pyplot as plt import numpy as np fig = plt.figure() # an empty figure with no axes fig.suptitle('No axes on this figure') # Add a title so we know which it is fig, ax_lst = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes plt.show() ![]() ![]() ![]() ![]() |
これはあなたが「プロット」と考えるものであり、データ空間を持つ画像の領域です。 与えられた Figure は多くの Axes を含むことができますが、与えられた Axes オブジェクトは 1 つの Figure にしか存在できません。 Axes には、データ制限を処理する 2 つ( Axis と Axis の違いに注意してください)の 2 つ(または3Dの場合は 3 つ)の Axis オブジェクトが含まれます(データの制限は、set_xlim() および set_ylim() Axes メソッド)。 各軸には、タイトル( set_title() で設定)、x ラベル( set_xlabel() で設定)、およびyラベルセット( set_ylabel() で設定)があります。 Axes クラスとそのメンバー関数は、オブジェクト指向インタフェースを扱うための主要なエントリポイントです。 |
これらは、数行のようなオブジェクトです。 彼らは、グラフの限界を設定し、目盛り(軸上のマーク)と目盛り(目盛りを示す文字列)を生成します。 ティックの位置は Locator オブジェクトによって決定され、ティックラベル文字列は Formatter によってフォーマットされます。 正しい Locator と iFormatter を組み合わせることで、ティックの位置とラベルをきめ細かく制御できます。 |
図で見ることのできる基本的なものは、アーティスト(図、軸、枢軸のオブジェクトさえも)です。 これには、Text オブジェクト、Line2D オブジェクト、コレクションオブジェクト、Patch オブジェクトなどがあります。 Figure がレンダリングされると、すべてのアーティストがキ>ャンバスに描画されます。 ほとんどのアーティストは Axes に縛られています。 そのようなアーティストは複数の Axes で共有することも、1 つの Axes から別の Axes に移動することもできません。 |
すべてのプロット関数は、入力として np.array または np.ma.masked_array を想定しています。 pandas データオブジェクトや np.matrix などの「配列のような」クラスは、意図したとおりに動作する場合と動作しない場合があります。 プロットする前にこれらを np.array オブジェクトに変換するのが最善です。 たとえば、pandas.DataFrame を変換するには a = pandas.DataFrame(np.random.rand(4,5), columns = list('abcde')) a_asndarray = a.valuesnp.matrixを変換する b = np.matrix([[1,2],[3,4]]) b_asarray = np.asarray(b) |
Matplotlib はパッケージ全体です。 matplotlib.pyplot は matplotlib のモジュールです。 ピラブは matplotlib の横にインストールされるモジュールです。 Pyplot は、基本的なオブジェクト指向プロットライブラリに状態マシンインタフェースを提供します。 ステートマシンは、暗黙的かつ自動的に図と軸を作成して、目的のプロットを実現します。 例えば: # sphinx_gallery_thumbnail_number = 3 import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2, 100) plt.plot(x, x, label='linear') plt.plot(x, x**2, label='quadratic') plt.plot(x, x**3, label='cubic') plt.xlabel('x label') plt.ylabel('y label') plt.title("Simple Plot") plt.legend() plt.show() ![]() ![]() plt.plot を最初に呼び出すと、必要な Figure と Axes が自動的に作成され、目的のプロットが得られます。 その後 plt.plot を呼び出すと、現在の軸が再利用され、それぞれ別の行が追加されます。 タイトル、凡例、および軸ラベルを設定すると、自動的に現在の軸が使用され、タイトルが設定され、凡例が作成され、軸にラベルが付けられます。 pylab は、matplotlib.pyplot (プロット用)と numpy (数学用と配列用)を 1 つの名前空間にまとめてインポートする便利なモジュールです。 ピラブは廃止され、名前空間の汚染のためにその使用は強く推奨されていません。 代わりに pyplot を使用してください。 非インタラクティブなプロットの場合は、プロットを作成するために pyplot を使用し、プロットするために OO インターフェイスを使用することをお勧めします。 |
このドキュメントとサンプルを見ると、さまざまなコーディングスタイルと使用パターンが見つかります。 これらのスタイルは完全に有効で、長所と短所があります。 ちょうどすべての例を別のスタイルに変換して同じ結果を得ることができます。 唯一の注意点は、独自のコードのコーディングスタイルを混同しないようにすることです。 注意さまざまなスタイルのうち、正式にサポートされているものが 2 つあります。 したがって、これらは matplotlib を使用するための好ましい方法です。 パイプロスタイルの場合、スクリプトの上部にあるインポートは、通常、次のようになります。 import matplotlib.pyplot as plt import numpy as np次に、np.arange、np.zeros、np.pios、plt.figure、plt.plot、plt.show などを呼び出します。図を作成するために pyplot インターフェイスを使用し、残りのオブジェクトメソッドを使用します : import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 10, 0.2) y = np.sin(x) fig, ax = plt.subplots() ax.plot(x, y) plt.show() ![]() ![]() なぜ、MATLAB スタイル(グローバルな状態とフラットな名前空間に依存している)の代わりに余分な型付けをするのですか? この例のような非常に単純なものについては、唯一の利点は学問的なものです。より細かいスタイルは、より明快で、どこから来て、何が起こっているかがより明確です。 より複雑なアプリケーションの場合、この明示と明快さはますます重要になり、より豊かでより完全なオブジェクト指向のインターフェースにより、プログラムの作成と保守が容易になります。 典型的には、同一のプロットを何度も何度も繰り返すが、データセットは異なるため、プロットを行うための特殊な関数を書く必要があります。 推奨される関数のシグネチャは次のようなものです。 import matplotlib.pyplot as plt import numpy as np def my_plotter(ax, data1, data2, param_dict): """ A helper function to make a graph Parameters ---------- ax : Axes The axes to draw to data1 : array The x data data2 : array The y data param_dict : dict Dictionary of kwargs to pass to ax.plot Returns ------- out : list list of artists added """ out = ax.plot(data1, data2, **param_dict) return out # which you would then use as: data1, data2, data3, data4 = np.random.randn(4, 100) fig, ax = plt.subplots(1, 1) my_plotter(ax, data1, data2, {'marker': 'x'}) plt.show() ![]() ![]() または、2つのサブプロットが必要な場合: import matplotlib.pyplot as plt import numpy as np def my_plotter(ax, data1, data2, param_dict): """ A helper function to make a graph Parameters ---------- ax : Axes The axes to draw to data1 : array The x data data2 : array The y data param_dict : dict Dictionary of kwargs to pass to ax.plot Returns ------- out : list list of artists added """ out = ax.plot(data1, data2, **param_dict) return out # which you would then use as: data1, data2, data3, data4 = np.random.randn(4, 100) fig, (ax1, ax2) = plt.subplots(1, 2) my_plotter(ax1, data1, data2, {'marker': 'x'}) my_plotter(ax2, data3, data4, {'marker': 'o'}) plt.show() ![]() ![]() 繰り返しますが、これらの単純な例では、このスタイルは過剰なもののように見えますが、グラフがやや複雑になると、それは報われます。 |
ウェブサイトやメーリングリストの多くのドキュメントは、「バックエンド」を指しており、多くの新規ユーザーはこの用語で混乱しています。 matplotlib は、さまざまなユースケースと出力フォーマットをターゲットにしています。 matplotlib を Python シェルからインタラクティブに使用する人もいれば、プロンプトウィンドウにコマンドを入力するとポップアップが表示されることがあります。 Jupyter のノートブックを実行し、迅速なデータ分析のためのインラインプロットを描く人もいます。豊富なアプリケーションを構築するために、wxpythonやpygtk のようなグラフィカルユーザインタフェースに matplotlib を組み込む人もいます。バッチスクリプトで matplotlib を使用して数値シミュレ>ーションからポストスクリプトイメージを生成する人もいれば、Web アプリケーションサーバを実行してグラフを動的に提供する人もいます。 これらのユースケースをすべてサポートするために、matplotlib は異なる出力をターゲットとすることができ、これらの機能のそれぞれをバックエンドと呼びます。 「フロントエンド」はユーザが直面するコード、すなわちプロットコードであり、「バックエンド」はその背後にあるすべてのハードワークをフィギュアとする。バックエンドには、ユーザーインターフェイスのバックエンド( pygtk、wxpython、tkinter、qt4、または macosx で使用するための「インタラクティブバックエンド」とも呼ばれます)とハードコピーのバックエンドがあり、画像ファイル( PNG、SVG、PDF、 「非対話型バックエンド」とも呼ばれます)。 バックエンドの設定には4つの方法があります。それらが互いに競合する場合、以下のリストの最後の方法が使用されます。 use() を呼び出すと、matplotlibrcの設定が上書きされます。
注意バイナリインストーラや Linux ディストリビューションパッケージなどの matplotlib の典型的なインストールでは、良いデフォルトのバックエンドが既に設定されているので、対話的な作業とスクリプトからのプロットが可能で、スクリーンやファイルへの出力も可能です。少なくとも最初は上記の方法のいずれかを使う必要はありません。 ただし、グラフィカルユーザーインターフェイスや Web アプリケーションサーバー( Web アプリケーションサーバー の Matplotlib )を作成したり、何が起こっているのかをよりよく理解する必要がある場合は、を参照してください。グラフィカルユーザインタフェースのために少しカスタマイズ可能にするため、matplotlib はレンダラの概念(実際に描画を行うもの)をキャンバス(描画が行われる場所)から分離します。ユーザーインターフェイス用の標準的なレンダラは、アンチグレインジオメトリ C ++ライブラリを使用して Figure のラスタ(ピクセル)イメージを作成する Agg です。 macosx を除くすべてのユーザーインターフェイスは、WXAgg、GTK3Agg、QT4Agg、QT5Agg、TkAgg などの agg レンダリングで使用できます。さらに、いくつかのユーザーインターフェイスは他のレンダリングエンジンをサポートしています。たとえば、GTK + 3 では、Cairo レンダリング(バックエンド GTK3Cairo )を選択することもできます。 レンダリングエンジンでは、ベクトルレンダラーまたはiラスターレンダラーを区別することもできます。ベクターグラフィックス言語では、「この点からこの点まで線を引く」のような描画コマンドが発行されるため、スケールフリーであり、ラスタバックエンドは DPI 設定に依存する精度の線のピクセル表現を生成します。 matplotlib レンダラの概要を以下に示します(それぞれに裏打ちされたものです;これらは非対話型のバックエンドで、ファイルに書き込むことができます)。
|
Jupyter ウィジェットのエコシステムは、Matplotlib で直接サポートするには速すぎます。 ipympl をインストールするにはpip install ipympl jupyter nbextension enable --py --sys-prefix ipymplまたは conda install ipympl -c conda-forge詳細は、jupyter-matplotlib を参照してください。 |
GTK3 バックエンド( GTK3Agg と GTK3Cairo の両方)は、カイロ( pycairo >= 1.11.0 または cairocffi )に依存しています。 |
QT_API 環境変数は、それぞれ PyQt4 または PySide を使用するために pyqt または pyside に設定できます。 使用されるバインディングのデフォルト値は PyQt4 なので、matplotlib はまずインポートを試みます。インポートが失敗した場合、PySide をインポートしようとします。 |
インタラクティブバックエンド(バックエンドとは? を参照)を使用すると、画面にプロットすることができますが、それだけでは必要ありません。プロットがスクリーンに描画されたかどうか、またプロットがスクリーンに描画された後にスクリプトセッションまたはシェルセッションが続くかどうかは、呼び出される関数とメソッド、および matplotlib が「対話モード"デフォルトのブール値は matplotlibrc ファイルによって設定され、他の設定パラメータと同様にカスタマイズできます(スタイルシートと rcParamsでMatplotlib をカスタマイズする を参照)。 matplotlib.interactive() を介して設定することもでき、その値は matplotlib.is_interactive() を介して照会することができます。スクリプトやシェルでプロットコマンドのストリームの途中でインタラクティブモードをオンまたはオフにすることはめったに必要ではなく、混乱させる可能性があるので、以下ではすべてのプロットがインタラクティブモードでオンまたはオフのどちらかで行われると仮定します。 注意対話モードは、matplotlib.pyplot.ion() でオンにし、matplotlib.pyplot.ioff() でオフにすることもできます。 注意 |
通常の python プロンプトから、またはオプションなしで ipython を呼び出した後で、これを試してみてください:import matplotlib.pyplot as plt plt.ion() plt.plot([1.6, 2.7])バージョン 1.0.1 以降を実行していて、デフォルトでインタラクティブバックエンドがインストールされ、選択されていると仮定すると、プロットが表示され、ターミナルプロンプトもアクティブでなければなりません。 次のような追加のコマンドを入力できます。 plt.title("interactive test") plt.xlabel("index")プロットは各行の後に更新されています。 バージョン1.5以降、他の手段でプロットを変更すると、ほとんどのバックエンドで自動的に表示>が更新されるはずです。 Axes インスタンスへの参照を取得し、そのインスタンスのメソッドを呼び出します。 ax = plt.gca() ax.plot([3.1, 2.2])特定のバックエンド( macosx など)または古いバージョンの matplotlib を使用している場合は、プロットに追加された新しい行がすぐに表示されないことがあります。 この場合、プロットを更新するためには明示的に draw() を呼び出す必要があります: plt.draw() |
対話モードでは、pyplot関数は自動的に画面に描画します。 対話的にプロットする場合、pyplot 関数に加えてオブジェクトメソッド呼び出しを使用する場合は、プロットを更新するたびに draw() を呼び出します。 1 つ以上の図形を生成し、新しい図形集合を終了または生成する前に表示するスクリプトで、非対話モードを使用します。 その場合は、show() を使用して Figure を表示し、手動で破棄するまで実行をブロックします。 |
インタラクティブモードでデータを探索する場合でも、プログラムによって多くのプロットを保存する場合でも、パフォーマンスをレンダリングすることは、パイプラインの厄介なボトルネックになります。 Matplotlib は、プロットの外観のわずかな変更(設定可能な許容値まで)を犠牲にしてレンダリング時間を大幅に短縮する2つの方法を提供します。 レンダリング時間を短縮するために使用できるメソッドは、作成されているプロットのタイプによって異なります。 |
線分(典型的なラインプロット、ポリゴンのアウトラインなど)を持つプロットの場合、レンダリングのパフォーマンスは matplotlibrc ファ>イルの path.simplify および path.simplify_threshold パラメータによって制御できます(詳しくは、スタイルシートと rcParams を使用した Matplotlib のカスタマイズ を参照してください)。 matplotlibrc ファイルに関する情報)。 path.simplify パラメータは、線分が単純化されているかどうかを示すブール値です。 path.simplify_threshold パラメータは、線分の簡略化の程度を制御します。 閾値が高いほどレンダリングが速くなります。 次のスクリプトは、まず単純化せずにデータを表示し、同じデータを簡略化して表示します。 両方ともやり取りしてみてください: import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl # Setup, and create the data to plot y = np.random.rand(100000) y[50000:] *= 2 y[np.logspace(1, np.log10(50000), 400).astype(int)] = -1 mpl.rcParams['path.simplify'] = True mpl.rcParams['path.simplify_threshold'] = 0.0 plt.plot(y) plt.show() mpl.rcParams['path.simplify_threshold'] = 1.0 plt.plot(y) plt.show() ![]() ![]() ![]() ![]() Matplotlib は現在デフォルトで 1/9 という控えめな簡素化しきい値になっています。別の値を使用するようにデフォルト設定を変更する場合は、matplotlibrc ファイルを変更することができます。あるいは、インタラクティブなプロット(最大限の単純化を含む)のための新しいスタイルと、(最小限の単純化を伴う)パブリケーション品質プロットのための別のスタイルを作成し、必要に応じてアクティブにすることもできます。これらのアクションの実行方法については、スタイルシートと rcParams を使用した Matplotlib のカスタマイズ を参照してください。 単純化は、次の線分のベクトルへの垂直距離(表示座標空間で測定)が path.simplify_threshold パラメータよりも大きくなるまで、線分を 1 つのベクトルに繰り返しマージすることによって機能します。 注意 |
マーカは、線分より堅牢ではありませんが、簡略化することもできます。 マーカーの簡略化は、( Markevery プロパティを使用して) Line2D オブジェクトでのみ使用できます。 matplotlib.pyplot.plot() や matplotlib.axes.Axes.plot() など、Line2D の構築パラメータが渡される場所は、markevery パラメータを使用することができます:plt.plot(x, y, markevery=10)markevery 引数は、素朴なサブサンプリング、または均等に( x 軸に沿って)サンプリングを試みることを可能にします。 詳細については Markevery デモを参照してください。 |
バックエンド(バックエンドとは? を参照)を使用している場合は、agg.path.chunksize rc パラメータを使用できます。 これにより、チャンクサイズを指定することができ、多くの頂点を持つ行は、複数の行に分割されます。各行は、agg.path.chunksize 多くの頂点を持ちます。 ( agg.path.chunksize がゼロでない場合は、チャンクはありません)。ある種のデータでは、適切なサイズにラインをチャンクするとレンダリング時間が大幅に短縮されます。 次のスクリプトは、最初にチャンクサイズの制限なしでデータを表示し、チャンクサイズが 10,000 の同じデータを表示します。 数値が大きい場合は、GUIを最大化して対話してみてください。 import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcParams['path.simplify_threshold'] = 1.0 # Setup, and create the data to plot y = np.random.rand(100000) y[50000:] *= 2 y[np.logspace(1,np.log10(50000), 400).astype(int)] = -1 mpl.rcParams['path.simplify'] = True mpl.rcParams['agg.path.chunksize'] = 0 plt.plot(y) plt.show() mpl.rcParams['agg.path.chunksize'] = 10000 plt.plot(y) plt.show() ![]() ![]() ![]() ![]() |
高速スタイルは、大量のデータをプロットする速度を上げるために、単純化パラメータとチャンクパラメータを合理的な設定に自動的に設定するために使用できます。 次のコマンドを実行するだけで簡単に使用できます。import matplotlib.style as mplstyle mplstyle.use('fast')それは非常に軽量なので、他のスタイルとうまく連動します。ファーストスタイルが最後に適用されて他のスタイルが設定を上書きしないよ>うにしてください: mplstyle.use(['dark_background', 'ggplot', 'fast']) |
Usage Guide |
|