1. ホーム
  2. python

[解決済み] matplotlib のカラーサイクルの状態を取得する

2023-01-29 04:44:47

質問

matplotlibのカラーサイクルの現在の状態を問い合わせることは可能ですか?言い換えれば、関数 get_cycle_state という関数がありますか?

>>> plot(x1, y1)
>>> plot(x2, y2)
>>> state = get_cycle_state()
>>> print state
2

ここで、私は状態がプロットで使用される次の色のインデックスであることを期待します。代わりに、それが次の色(上の例では、デフォルトのサイクルのための"r")を返した場合、それも良いでしょう。

どのように解決するのですか?

色サイクルイテレータにアクセスする

基本となるイテレータにアクセスするための "user-facing" (すなわち "public") メソッドはありませんが、(慣習により) "private" メソッドを通じてアクセスすることができます。 しかし、この方法では iterator の状態を変更することなく取得することはできません。

カラーサイクルの設定

簡単な余談です。色とプロパティのサイクルは様々な方法で設定することができます(例えば ax.set_color_cycle をバージョン <1.5 で使用したり ax.set_prop_cycler を使用することができます。) を見てみてください。 の例を見てください。 または 以前のスタイルはこちら .

基礎となるイテレータにアクセスする

しかし、イテレートにアクセスするためのパブリックなメソッドはありませんが、与えられた軸オブジェクト( ax ) に対して _get_lines ヘルパークラスのインスタンスです。 ax._get_lines は少しわかりにくい名前ですが、これは舞台裏の機械で plot コマンドで処理できるようにするための裏方の機械です。 plot が呼び出されることがあります。 特に、どの色を自動的に割り当てるかを追跡するのはこのコマンドです。同様に ax._get_patches_for_fill があり、デフォルトの塗りつぶし色とパッチのプロパティを循環させることを制御します。

何はともあれ、色サイクルの反復可能性は ax._get_lines.color_cycle で、線分については ax._get_patches_for_fill.color_cycle を使用します。 matplotlib >=1.5 では、これは次のように変更されました。 を使うようになりました。 cycler ライブラリ と呼ばれるもので、イテラブルは prop_cycler ではなく color_cycle を生成し dict を生成します。

全部でこんな感じになります。

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
color_cycle = ax._get_lines.color_cycle
# or ax._get_lines.prop_cycler on version >= 1.5
# Note that prop_cycler cycles over dicts, so you'll want next(cycle)['color']

の状態を表示することはできません。 iterator

しかし、このオブジェクトは "bare".の状態です。 iterator . 次の項目を簡単に取得できる(例えば next_color = next(color_cycle) を取得することができますが、それはつまり次の色 の後に がプロットされることになります。 設計上、イテレータを変更することなく現在の状態を取得する方法はありません。

v1.5 以上であれば、そのような場合にも cycler オブジェクトを取得できれば、その現在の状態を推測することができます。しかし cycler オブジェクト自体はどこにも(公的にも私的にも)アクセスできません。その代わりに itertools.cycle インスタンスのみです。 cycler オブジェクトから作成された インスタンスにアクセスできます。 いずれにせよ、色/プロパティサイクラーの根本的な状態にアクセスする方法はありません。

代わりに前にプロットされたアイテムの色に一致させる

あなたのケースでは、ちょうどプロットされたものの色に合わせたいようです。 色/プロパティが何であるかを決定しようとするのではなく、プロットされたもののプロパティに基づいて新しいアイテムの色/等を設定します。

たとえば、あなたが説明したケースでは、私は次のようにします。

import matplotlib.pyplot as plt
import numpy as np

def custom_plot(x, y, **kwargs):
    ax = kwargs.pop('ax', plt.gca())
    base_line, = ax.plot(x, y, **kwargs)
    ax.fill_between(x, 0.9*y, 1.1*y, facecolor=base_line.get_color(), alpha=0.5)

x = np.linspace(0, 1, 10)
custom_plot(x, x)
custom_plot(x, 2*x)
custom_plot(x, -x, color='yellow', lw=3)

plt.show()

<イグ

これが唯一の方法というわけではありませんが、この場合、事前にプロットされた線の色を取得しようとするよりもきれいな方法です。