Pandas: API:バックエンドをプロットするパンダのAPIを定義します

作成日 2019年06月09日  ·  44コメント  ·  ソース: pandas-dev/pandas

#26414では、パンダのプロットモジュールを、さまざまなバックエンドと現在のmatplotlibバックエンドを呼び出すことができる一般的なプロットフレームワークに分割しました。 アイデアは、他のバックエンドをより簡単な方法で実装し、パンダユーザーが一般的なAPIで使用できるということです。

現在のmatplotlibバックエンドで定義されているAPIには、次にリストされているオブジェクトが含まれていますが、このAPIはおそらく簡略化できます。 質問/提案のリストは次のとおりです。

APIに保持するための議論の余地のないメソッド( Series.plot(kind='line') ...機能を提供します):

  • LinePlot
  • 棒グラフ
  • BarhPlot
  • HistPlot
  • 箱ひげ図
  • KdePlot
  • AreaPlot
  • PiePlot
  • 散布図
  • HexBinPlot

パンダで提供されるプロット関数(例: pandas.plotting.andrews_curves(df)

  • andrews_curves
  • autocorrelation_plot
  • bootstrap_plot
  • lag_plot
  • parallel_coordinates
  • radviz
  • scatter_matrix
  • テーブル

それらはAPIの一部である必要があり、他のバックエンドもそれらを実装する必要がありますか? .plotの形式に変換するのは理にかなっていますか(例: DataFrame.plot(kind='autocorrelation') ...)? APIを使用しない、またはサードパーティのモジュールに移行するのは理にかなっていますか?

削除できる可能性のある冗長なメソッド:

  • hist_series
  • hist_frame
  • 箱ひげ図
  • boxplot_frame
  • boxplot_frame_groupby

boxplot場合、現在、プロットを生成するいくつかの方法があります(主に同じコードを呼び出します)。

  1. DataFrame.plot.boxplot()
  2. DataFrame.plot(kind='box')
  3. DataFrame.boxplot()
  4. pandas.plotting.boxplot(df)

個人的には、4番を非推奨にし、3番については、バックエンドで個別のboxplot_frameメソッドを非推奨にするか、少なくとも必要としませんが、 BoxPlotを再利用してみてください(3番のコメントについては、同じhist適用されます)。

boxplot_frame_groupby場合、詳細を確認しませんでしたが、 BoxPlotをこれに再利用できるかどうかわかりませんか?

コンバーターを登録する機能:

  • 登録
  • 登録解除

それらは他のバックエンドにとって意味がありますか?

パンダ0.23で非推奨、削除予定:

  • tsplot

これらの各関数が実際に何をするかを確認するには、 @ liirusukによるこのノートブックが役立つ場合があります。

CC:@ pandas -dev / @ tacaswell@ jakevdp@ philippjfr 、@ PatrikHlobil

API Design Clean Needs Discussion Visualization

最も参考になるコメント

これがエントリポイントベースの実装です

diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py
index 0610780ed..c8ac12901 100644
--- a/pandas/plotting/_core.py
+++ b/pandas/plotting/_core.py
@@ -1532,8 +1532,10 @@ class PlotAccessor(PandasObject):

         return self(kind="hexbin", x=x, y=y, C=C, **kwargs)

+_backends = {}

-def _get_plot_backend(backend=None):
+
+def _get_plot_backend(backend="matplotlib"):
     """
     Return the plotting backend to use (e.g. `pandas.plotting._matplotlib`).

@@ -1546,7 +1548,14 @@ def _get_plot_backend(backend=None):
     The backend is imported lazily, as matplotlib is a soft dependency, and
     pandas can be used without it being installed.
     """
-    backend_str = backend or pandas.get_option("plotting.backend")
-    if backend_str == "matplotlib":
-        backend_str = "pandas.plotting._matplotlib"
-    return importlib.import_module(backend_str)
+    import pkg_resources  # slow import. Delay
+    if backend in _backends:
+        return _backends[backend]
+
+    for entry_point in pkg_resources.iter_entry_points("pandas_plotting_backends"):
+        _backends[entry_point.name] = entry_point.load()
+
+    try:
+        return _backends[backend]
+    except KeyError:
+        raise ValueError("No backend {}".format(backend))
diff --git a/setup.py b/setup.py
index 53e12da53..d2c6b18b8 100755
--- a/setup.py
+++ b/setup.py
@@ -830,5 +830,10 @@ setup(
             "hypothesis>=3.58",
         ]
     },
+    entry_points={
+        "pandas_plotting_backends": [
+            "matplotlib = pandas:plotting._matplotlib",
+        ],
+    },
     **setuptools_kwargs
 )

なかなかいいと思います。 サードパーティのパッケージは、setup.py(またはpyproject.toml)を変更して次のようなものを含めます

entry_points={
    "pandas_plotting_backends": ["altair = pdvega._pandas_plotting_backend"]
}

ネーミングと実装の間の緊密な結合を壊すのが好きです。

全てのコメント44件

自己相関のようなものは、スワップ可能なバックエンドAPIから除外すると思います。

df.boxplotやhistのようなものは、.plot APIとは少し異なる動作をするため、残したと思います。 それらをバックエンドAPIの一部にすることはお勧めしません。

数か月前に提案されたバックエンドAPIの開始点は次のとおりです: https

少なくともhvplot (残りはチェックしていません)はすでにandrews_curvesscatter_matrixlag_plot 、のような関数を提供していることを言及する価値があると思います。 ..

すべてのバックエンドにそれらを強制的に実装させたくない場合は、選択したバックエンドがそれらを実装しているかどうかを確認し、デフォルトでmatplotlibプロットにすることができますか?

boxplothistまったく同じように動作すると仮定しましたが、 Series.plot.hist()ショートカットSeries.hist()ました。 「ショートカット」はプロットグリッドを示していますが、それ以外は違いは見られません。

IMO、このオプションの主な値は.plot名前空間です。

ユーザーがhvplotのAndrewの曲線プロットが必要な場合は、関数をインポートする必要があります
hvplotから、そこにデータフレームを渡します。

7:17 AMマルク・ガルシアの日、2019年6月9日に[email protected]書きました:

少なくともhvplot(チェックしなかった
rest)は、andrews_curvesのような関数をすでに提供しています。
scatter_matrix、lag_plot、..。

すべてのバックエンドにそれらを実装するように強制したくない場合は、次のことができます。
選択したバックエンドがそれらを実装しているかどうかを確認し、デフォルトで
matplotlibプロット?

私は箱ひげ図と履歴がまったく同じように動作すると仮定しましたが、
Series.plot.hist()のショートカットSeries.hist()。 「ショートカット」は
グリッドをプロットしますが、それ以外は違いは見られません。


あなたは言及されたチームに所属しているので、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/pandas-dev/pandas/issues/26747?email_source=notifications&email_token=AAKAOIRLJHBMXMXKK2IG2NDPZTYFPA5CNFSM4HWIMEK2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAKAOISDHL6H7PVOOJAQXELPZTYFPANCNFSM4HWIMEKQ

私はそれが理にかなっていると思うが、我々はそれを行うならば、私たちはそれらを動かすべきだと思いますpandas.plotting.matplotlib.andrews_curvesの代わりに、 pandas.plotting.andrews_curves

@TomAugspurger詳細を確認する必要がありますが、 andrews_curvesscatter_matrix ...を.plot()構文に移動することが可能かどうかについても実験します。これにより、すべての人にとって物事がよりシンプルで簡単になると思います(私たち、サードパーティライブラリ、およびユーザー)。

プロット関数に渡される追加のkwargに関して、ここでの意図は何ですか? 追加のバックエンドは、すべてのmatplotlibスタイルのプロットカスタマイズの機能を複製しようとする必要がありますか、それとも特定のバックエンドで使用されるキーワードに対応するキーワードを渡すことができるようにする必要がありますか?

最初のオプションは理論的には素晴らしいですが、すべての非matplotlibプロットバックエンドは、本質的に完全ではない非互換性のロングテールを備えた独自のmatplotlib変換レイヤーを本質的に実装する必要があります(mpld3を作成しようとした人としての経験から言えば数年前)。

2番目のオプションは、互換性の観点からはそれほど優れていませんが、より合理的な一連の期待を持って他のバックエンドを追加することができます。

それは彼らが彼らをどうするかについてのバックエンド次第だと思います。 100%を達成する
バックエンド間の互換性は実際には実現可能ではありませんが、
戻り型はmatplotlibAxesではなくなるためです。 で、もし
リターンタイプには互換性がないので、バックエンドはないと思います
考えられるすべてのキーワード引数を処理するために、後ろ向きに曲がる必要があります。

だからパンダは**kwargsがに渡されることを文書化する必要があると思います
基礎となるプロットエンジン、そして彼らは彼らが好きなことを何でもすることができます
彼ら。

2019年6月10日月曜日午前10時42分ジェイクヴァンデルプラス[email protected]
書きました:

プロットに渡される余分なkwargsに関するここでの意図は何ですか
関数? 追加のバックエンドが複製を試みた場合
すべてのmatplotlibスタイルのプロットカスタマイズの機能、またはそれらが必要
特定の人が使用するキーワードに対応するキーワードを渡すことができます
バックエンド?

最初のオプションは理論的には素晴らしいでしょうが、すべてが必要になります
本質的に独自のmatplotlibを実装するための非matplotlibプロットバックエンド
非互換性のロングテールを持つ変換レイヤー
本質的に完全になることはありません(
数年前にmpld3を作成しようとしました)。

2番目のオプションは、
互換性がありますが、他のバックエンドをさらに追加することができます
合理的な一連の期待。


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/pandas-dev/pandas/issues/26747?email_source=notifications&email_token=AAKAOIS3IBV4XSSY7BPSCF3PZZY5LA5CNFSM4HWIMEK2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKT
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAKAOIQ3GYOGAPUZ4LSNK2DPZZY5LANCNFSM4HWIMEKQ

これがばかげた質問である場合は申し訳ありませんが、基本的に既定のプロットのグループであるプロット「API」を定義すると、すべてのバックエンドが多かれ少なかれ同じ出力を生成しませんか? これはどのような新機能を有効にすることを意味しますか? おそらくパンダからベガの輸出業者のようなものですか?

すべてのバックエンドが多かれ少なかれ同じ出力を生成すると言うのは正しくないと思います。

たとえば、matplotlibは静的なグラフには非常に優れていますが、ポータブルなインタラクティブなグラフの作成には優れていません。

一方、bokeh、altair、etal。 インタラクティブなチャートには最適ですが、静的なチャートのmatplotlibほど成熟していません。

同じAPIで両方を作成できることは大きなメリットです。

最初のオプションは理論的には素晴らしいですが、すべての非matplotlibプロットバックエンドは、本質的に完全ではない非互換性のロングテールを備えた独自のmatplotlib変換レイヤーを本質的に実装する必要があります(mpld3を作成しようとした人としての経験から言えば数年前)。

また、Matplotlibを、APIに関してすでに行っている以上にピン留めします。 パンダが公開したいスタイルのノブを宣言し、バックエンドの実装がそれが何を意味するのかを整理することを期待するのは理にかなっていると思います。 これは、 **kwargsを盲目的に通過させず、代わりに、返されたオブジェクトが、特定のバックエンドが事後スタイルのカスタマイズを実行できるようにするための「正しいもの」であることを保証することを意味する場合があります。

たとえば、matplotlibは静的なグラフには非常に優れていますが、ポータブルなインタラクティブなグラフの作成には優れていません。

@jakevdpに感謝し

物事がこの特定の道を行き過ぎてしまう前に、ここに別の解決策があります。

パンダのプロットAPIを仕様として宣言し、vizパッケージに具体的に実装するように依頼する代わりに、プロットの中間表現(vega JSONファイルなど)を生成し、バックエンドがそれを入力としてターゲットにするように促します。

利点は次のとおりです。

  1. 仕様として設計されていない、洗練されたパンダAPIの表現力に縛られていません。
  2. パンダをサポートするためにパッケージをプロットすることによって行われた作業は、IRを生成する他のpydataパッケージで利用できるようになります。
  3. pydataスペースでの交換の視覚化のための共通言語の促進
  4. より広く適用できるため、新しいツールがより強力になります
  5. それはそれらを書く努力をより合理的にします。 基本的に、改善されたインセンティブ。

Vega / Vega-liteは、最新の確立されたオープンなJSONベースのviz仕様言語として、数年かけて設計と実装に組み込まれ、その周りに構築された既存のツールは、この目的のために明示的に作成されたようです。 。 (しないでください)。

コンパイラが設計されているように、 frontend->IR->backendです。

少なくとも3つのパッケージがすでにAPIを実装しています。 パンダがする必要があるのは、バックエンドを変更してその使用法を文書化するためのオプションを提供することだけです。

2019年6月15日には、午後4時28で、pilkibun [email protected]書きました:

たとえば、matplotlibは静的なグラフには非常に優れていますが、ポータブルなインタラクティブなグラフの作成には優れていません。

@jakevdpに感謝し

物事がこの特定の道を行き過ぎてしまう前に、ここに別の解決策があります。

パンダのプロットAPIを仕様として宣言し、vizパッケージに具体的に実装するように依頼する代わりに、プロットの中間表現(vega JSONファイルなど)を生成し、バックエンドがそれを入力としてターゲットにするように促します。

利点は次のとおりです。

仕様として設計されていない、洗練されたパンダAPIの表現力に縛られていません。
パンダをサポートするためにパッケージをプロットすることによって行われた作業は、IRを生成する他のpydataパッケージで利用できるようになります。
pydataスペースでの交換の視覚化のための共通言語の促進
より広く適用できるため、新しいツールがより強力になります
それはそれらを書く努力をより合理的にします。 基本的に、改善されたインセンティブ。
Vega / Vega-liteは、最新の確立されたオープンなJSONベースのviz仕様言語として、数年かけて設計と実装に組み込まれ、その周りに構築された既存のツールは、この目的のために明示的に作成されたようです。 。 (しないでください)。

ご存知のとおり、フロントエンド-> IR->バックエンドは、コンパイラのように設計されています。


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。

#26753をマージし、プロットバックエンドをパンダから変更できるようになりました。 matplotlibコードを分割するとき、 SeriesPlotMethodsFramePlotMethodsをパンダ(matplotlibではない)側に残しました。 それは主にパンダ側にdocstringsを残すことでした。

しかし、バックエンドが行ったことは、それらのクラスを再実装することだったことがわかります。 したがって、現在、バックエンドにはプロットごとに1つのクラスがあると予想されます(例: LinePlotBarPlot )が、代わりにメソッドごとにプロットを持つクラスを実装します(例: hvPlot, or the same names as pandas for pdvega `)。

少なくとも最初のバージョンとしては、 hvplotpdvega APIを実装することが理にかなっていると思います。 パンダで、バックエンドが継承する抽象クラスを作成するだけです。

それがすべての人にとって理にかなっている場合は、抽象クラスを作成し、パンダにあるmatplotlibバックエンドを適応させることから始めます。これが完了したら、 hvplotpdvega (変更点)を適応させます。かなり小さいはずです)。

考え?

少なくとも最初のバージョンとしては、hvplotやpdvegaと同じようにAPIを実装するのが理にかなっていると思います。 パンダで、バックエンドが継承する抽象クラスを作成するだけです。

全体として、このアプローチはよりクリーンになると思います。 他のプロットバックエンドと話すことはできませんが、少なくともhvPlotでは、さまざまなプロットメソッドがかなりのコードを共有します。たとえば、 scatterlineareaはほぼ類似しており、それらの間でコードを共有するためにサブクラス化に依存したくない。 さらに、さまざまなバックエンドに追加のプロットタイプを追加するオプションが必要であり、追加のパブリックメソッドとしてそれらを公開することは、最も単純で最も自然なアプローチのように思われます。

念のために言ってI'd prefer not to rely on subclassing to share code between themますが、 class LinePlot(MPLPlot)になりますよね? そして、抽象基本クラスから継承するのは悪い考えだと思いませんか?

私は、バックエンドにパンダではないプロットタイプを定義させることに+1していると思います。 しかし、私はおそらく今はそれを実装しません。 パンダは1週間程度で発売する予定です。 そして、ユーザーがkind='foo'を提供し、バックエンドがメソッドfoo提供する場合、これはバックエンドのメソッドを盲目的に呼び出すよりも少し考える必要があると思います(たとえば、パラメーターの検証、またはそれが原因で一部のkindはドキュメントに含まれ、一部は含まれません)。

念のために言っておきますが、LinePlot(MPLPlot)クラスのように、サブクラス化に依存してコードを共有したくないと言った場合はどうでしょうか。 そして、抽象基本クラスから継承するのは悪い考えだと思いませんか?

はい、そうです。 より具体的には、私はこの種のことをする必要がないことを望みます:

class MPL1dPlot(MPLPlot):

    def _some_shared_method(self, ...):
        ...

class LinePlot(MPL1dPlot):
    ...

class AreaPlot(MPL1dPlot):
    ...

それが明確でない場合は申し訳ありません。

https://github.com/pandas-dev/pandas/pull/27009で現在提案されているクラスではなく、単一の関数として公開されている、より単純なAPIを非常に支持してい

バックエンドオプションが現在どのように機能するかに関する一般的な質問/コメント。 私がpdvega開発者であり、このバックエンドを利用できるようにするとします。 つまり、ユーザーがpd.options.plotting.backend = 'pdvega'実行する場合、 pdvegaライブラリにはトップレベルのplot関数が必要ですか?
1)ライブラリの作成者として、それは必ずしも公開したい関数ではありません(つまり、ライブラリの観点から見たトップレベルのplotメソッドの場合、ユーザーに必要なAPIである必要はありません。直接使用する)および2)この場合、実際にpd.options.plotting.backend = 'altair'を実行できるようにしたい場合がありますか? (Altair開発者がそれで問題ない場合)
つまり、基本的に私の質問は、バックエンド名に正確な1:1マッピングが必要であり、何がインポートされるのかということです。 (これは、提供されたバックエンド文字列のインポートを行うだけなので、現在必要です)。

編集:PR#26753で実際に似たようなことが議論されたことがわかります

パンダが使用できるバックエンドを知らない/制限しないと判断した場合(私はこれを強く支持しています)、バックエンドでどのように/何を呼び出すかを決定する必要があります。

私が取り組んでいるPRで実装および提案されているのは、オプションplotting.backendがモジュールであるということです( pdvegaaltairaltair.pandas 、または何でも)、そしてそのモジュールはパブリックplot関数を持たなければなりません、それは私たちが呼ぶものです。

オプションがpdvega場合、 pdvega.pandasをインポートする場合、関数にplot_pandasなどの名前を付ける場合など、他のオプションを検討できます。 提案された方法が最も簡単だと思いますが、もっと意味のある提案が他にあれば、喜んで変更します。

もう1つの議論は、ユーザーにバックエンドを手動でインポートするように強制したい場合です。

import pandas
import hvplot

pandas.Series([1, 2, 3]).plot()

そうすると、モジュールは自分自身を登録でき、エイリアスも登録できます(したがって、 set_optionはモジュールの名前以外の名前を理解できます)。 また、カスタム関数や機械(コンテキストマネージャーなど)を実装して、特定のバックエンドでプロットすることもできます。

そして、ボケでプロットするためにpandas.set_option('plotting.backend', 'bokeh')を実行するのは良いことかもしれませんが、それは私が個人的に好きではない2つのことを意味すると思います。

  • pandas.set_option('plotting.backend', 'bokeh')は、 import pandas_bokehが呼び出された場合にのみ機能し、ユーザーを混乱させます。
  • また、 bokehにプロットするモジュールが1つしかないことも意味します。 これは真実である必要はなく、パンダがボケのバックエンドをプロットするのではなく、ボケで直接プロットしているという誤った印象をユーザーに与えます。

@datapythonista詳細な回答をありがとう。 最初のリリースではそのままにしておいて問題ありません(エイリアスの可能性はいつでも後で追加できます)。

ユーザーがhvplotのAndrewの曲線プロットが必要な場合は、hvplotから関数をインポートし、そこにデータフレームを渡す必要があります。

+1、バックエンドを介してすべての追加のプロット関数を公開することもしません。

しかし、それらをpandas.plotting.matplotlibに移動することについて

pandas.set_option( 'ploting.backend'、 'bokeh')は、import pandas_bokehが呼び出された場合にのみ機能し、ユーザーを混乱させます。

エントリポイントを使用して拡張機能を登録する場合、これが当てはまる必要はありません。システムにパッケージをインストールすると、エントリポイントが登録され、パンダに表示されます。 たとえば、これは、ユーザーがインストールした可能性のあるさまざまなレンダラーを検出するためにAltairが使用するものです。

また、その価値については、これが実行されたら、おそらくpdvegaを廃止し、関連するコードをpandas_altairなどの名前の新しいパッケージに移動すると思います。

@datapythonista 0.25.0より前のプロットバックエンドAPIの範囲を決定する必要があると思います(ただし、RCではありません)。

その他のプロット関数(およびhist / boxplot)を維持することに賛成ですか?

@datapythonistaは、PRをマージした

@jreback APIに同意するまで、これを開いたままにしておきます。 @ TomAugspurger@jorisvandenbosscheは、アクセサープロット以外はバックエンドに委任したくありませんでした。

パンダをプロットするために私がすること-バックエンドは次です。

リリースの場合:

  • そのままにしておくと、hvplotは、アクセサーからのものとそうでないものを含め、すべてのプロットを実装します。 そして、私はすべてを委任することで物事をシンプルに保ちます。
  • 上記からregister_convertersを除外するかどうかはわかりません。 少なくとも、名前をregister_matplotlib_convertersから変更する必要があります。

次のリリースの場合:

  • 重複するすべてのpandas.plotting.boxplotSeries.hist 、..を非推奨にします。
  • アクセサー(andrew_curves、radviz、parallel_curves、...)から呼び出されるすべてのプロットを移動します。

バックエンドAPIの初期リリースでは、すべてを含めるのではなく、公開する内容をより保守的にしたいと思います。 削除するよりも、後で追加する方がはるかに簡単です。

個人的には、これらすべてのその他のプロットをアクセサーに移動することもありません(散布行列などの例外がある場合があります)。IMOandrew_curvesやradvizなどはメソッドに「価値がありません」。

つまり、バックエンドが追加の「種類」を実装できるようにしたいですか? したがって、パンダのように、どのアクセサメソッドを使用できるかを正確に決定する必要はありません。 ユーザーが特定のkind渡すか、属性にアクセスしようとした場合でも、カスタム__getattribute__を使用してバックエンドplot渡すことができます。

物事が今のようになっている理由を少し説明するだけです。 あなたが提案する変更をどのように実装するか、または一般的に物事を公開しない方法がよくわからないので、それは関連性があります。 ここで別の方法で行うことはできないと言っているのではなく、単に議論を豊かにすることです。

最初の決定は、matplotlibを使用してすべてのコードを別のモジュール( pandas.plotting._matplotlib )に移動することでした。 そうすることで、そのモジュールはどういうわけかmatplotlibバックエンドになりました。

pandas.plotting公開されていたものはすべて、そこで公開されています。 そして、物事をできるだけ簡単にするために、これらの関数はすべて、一度呼び出されると、バックエンドをロードし( _get_plot_backend呼び出す)、そこで関数を呼び出します。

ユーザーのパブリックAPIに変更はありません。ユーザーは、同じメソッドと関数を引き続き使用できます。 新しいものは公開していません。

私が理解していることですが、 andrew_curvesような既存のプロットがバックエンドに委任されていないと判断した場合、これは、ユーザーがバックエンドを選択する代わりに、matplotlibバックエンドを選択することを意味します。 少なくともhvplotがすでにandrew_curves実装していることを考えると、私は個人的にその要点を理解していません。 ユーザーがmatplotlibのandrew_curvesプロットを必要とする場合は、バックエンドを変更しない(または変更されている場合は再度設定する)のと同じくらい簡単です。 したがって、私たちが行う変更では、パンダに複雑さを追加することで、ユーザーの生活をはるかに困難にするだけです。

バックエンド開発者と仲良くなり、それほど主流ではないかもしれないプロットを実装するように強制したくない場合(それが理由の1つだと思いますか?)、選択したバックエンドにないものはすべてmatplotlibバックエンドにデフォルト設定できます?

未知の種類のプロットをバックエンドに委任することについて、私は今それを行うことに-1です。 確かにそれは最終的には理にかなっています。 しかし、パンダでいくつかのプロットの種類が文書化されていることと、私たちが文書化していない余分なプロットの種類があることは、少しハッキーだと感じます。 さまざまなバックエンドがユーザーにとってどのように機能するかについてフィードバックを受け取った後は、次のバージョンを待つことができると思います。また、詳細について話し合い、分析する時間があります。

ユーザーがmatplotlibのandrew_curvesプロットを必要とする場合は、バックエンドを変更しない(または変更されている場合は再度設定する)のと同じくらい簡単です。 したがって、私たちが行う変更では、パンダに複雑さを追加することで、ユーザーの生活をはるかに困難にするだけです。

ユーザーの生活を難しくすることはないと思います。 pandas.plotingからインポートする代わりに、hvplotのバージョンが必要な場合は、そこからインポートするだけです。 これは、オブジェクトで定義されているため、DataFrame.plotメソッドでは不可能なことです。 私にとって、それがバックエンドをプロットする主な理由です。

バックエンド開発者と仲良くなり、それほど主流ではないかもしれないプロットを実装するように強制したくない場合

私にとっては、すべてを実装する必要があるということではなく(バックエンドがすべてのプロットタイプ、IMOをサポートしていない場合はまったく問題ありません)、プロットバックエンドAPIの不要な拡張であり、これもそれに結びついています。 。
パンダを最初からやり直すとしたら、それらのその他のプロットタイプは含まれないと思います。 しかし、プロットバックエンドAPIを使用して、何らかの形で新しいことを始めています。

これについて他に何か意見はありますか?

@jorisvandenbosscheに同意しました。


これが失われないようにするために、setuptoolのエントリポイントを使用するという@jakevdpの提案は、インポート注文登録の問題を解決するために検討する価値があると思います: https

@jorisvandenbosscheコードでそれをどのように変更しますか? これらのメソッドの設定で定義されたバックエンドを取得する代わりに、matplotlibバックエンドを取得しますか? これは概念的には間違っていると思いますが、合意があれば大丈夫です。 matplotlibコードのデカップリングを残りの部分から元に戻すものはすべて-1です。

パンダに最初からそれらのプロットを含めないとおっしゃっていたので、それらを非推奨にする必要がありますか? SeriesまたはDataFrameメソッドではないすべてのプロットをサードパーティのパッケージに移動することに+1しています。 または、保持するのに十分重要なものがある場合は、それを移動して、他の.plot()として呼び出されるようにします。

私はパンダの非標準プロットを非推奨にします
外部パッケージに移動します

Jorisは少しオフラインです。

過去にこれについて話し合ったとき、彼と私の論文に対する立場は、メンテナンスの負担になるまでそのままにしておくことだと思います。

私たちが同じページにいるので、これは私たちが持っているものの要約であり、議論の状態についての私の理解です:

SeriesおよびDataFrameメソッドとして使用されます(選択したバックエンドに委任されたまま、そのままにしておくことができます)。

  • PlotAccessor
  • boxplot_frame
  • boxplot_frame_groupby
  • hist_frame
  • hist_series

その他のプロット(非推奨にするか、matplotlibバックエンドに委任するか、選択したバックエンドに委任するかを検討中):

  • 箱ひげ図
  • scatter_matrix
  • radviz
  • andrews_curves
  • bootstrap_plot
  • parallel_coordinates
  • lag_plot
  • autocorrelation_plot
  • テーブル

pandas.plotting他の公開のもの(議論中も):

  • plot_params
  • register_matplotlib_converters
  • deregister_matplotlib_converters

Other plotsセクションについては、個人的には現時点ではメンテナンスの負担だと思います。パンダから移動することで+1し、0.25で廃止します。

コンバーターやその他のものについては、 register_matplotlib_convertersが選択したプロットに委任しているため、現在の状態は確かに正しくありません。これはmatplotlibにすることはできません。 検討できると思うオプションは次のとおりです。

  • それらの名前をregister_converters / deregister_convertersに変更し、現在のものを廃止し、バックエンドに委任し続けます
  • それらをpandas.plottingからpandas.plotting.matplotlib移動します(これはmatplotlibバックエンドを公開することを意味するので、私はしません)
  • それらをそのままにして、選択したバックエンドではなくmatplotlibバックエンドに委任します(これは優れた設計上の決定というよりはハックだと思います。 pandas.plotting依存しないバックエンドを維持したいと思います)

その他のプロットのセクションについては、個人的には現時点ではメンテナンスの負担だと思います。パンダから移動することで+1し、0.25で廃止します。

「他の区画」がメンテナンスの負担になるとどう思いますか? 「その他」のプロットの履歴を見ると、 https

それらの名前をregister_converters / deregister_convertersに変更し、現在のものを廃止し、バックエンドに委任し続けます

これは意味がないと思います。 私たちはmatplotlibのために書かれ

過去数か月のメンテナンスの量が原因で、これらのプロットが負担になるという意味ではありませんでしたが、ユーザー向けの一貫性のある直感的なAPIと、優れたモジュラーを備えているという問題が原因です。私たちのためのコードデザイン。

コンバーターに関しては、バックエンドの作者が場合によってはmatplotlibと同等のものを実装したいかどうかはわかりません。 しかし、そうでなければ問題はないようであり、これらの関数は他のバックエンドの一部またはすべてに対して何もしません。 オプション2でも大丈夫ですが、きちんとは言えません。

しかし、ユーザー向けの一貫性のある直感的なAPIと、優れたモジュラーコード設計を備えているという問題が原因です。

ただし、これらはすでにDataFrame.plotと多少矛盾しています。 「misc」という名前は、次のことを意味します:)スワップ可能なバックエンドがあると、それはさらに悪化しますか? ユーザーコードを解約する価値がある範囲で? そうは思いません。

バックエンドの作者が場合によってはmatplotlibと同等のものを実装したいかどうかはわかりません。

そうは思いません。 これらのコンバーターのポイントは、パンダオブジェクトについてmatplotlibに教えることです。 バックエンドを実装しているライブラリは、すでにパンダに依存しているため、その問題は発生しません。

個人的には、主に複雑さの管理という観点から考えています。 単一のAPIを介してバックエンドに委任される標準のプロットAPIを使用すると、理解と保守が容易になります。 ユーザーとメンテナは、 kind引数を持つplot関数があり、これが選択したバックエンドで実行されることを知る必要があります。

バックエンドに異種プロットのセットがあり、同じAPIに従わないことに加えて、バックエンドを使用しますが、他のプロット用に選択されたものではなく、Matplotlibのものを使用すると、すべてのIMHOにとって非常に複雑になります。

そして、それらを移動するコストは私には小さいように思えます。私の推測では、ユーザーの大部分はそれらのプロットについてさえ知っていません。 そして、そうする人のために、彼らはただ追加のcondaパッケージをインストールして、 import pandas_plotting; pandas_plotting.andrews_curves(df)代わりにpandas.plotting.andrews_curves(df) import pandas_plotting; pandas_plotting.andrews_curves(df)を使う必要があるでしょう。

私には、少額の費用で勝つことがたくさんあるように思えますが、もちろんそれは単なる意見です。

交換可能なバックエンドがSeries / DataFrame.plot専用であることを文書化できますか? それはかなり単純なルールのようです。

私に不必要な複雑さを加えるハックのように感じます。 ドキュメントで説明しても、直感に反することはないと思います。

しかしとにかく、大したことではありません。 それが好ましいオプションである場合、これは私がそれを実装する方法です、少なくともコードの複雑さの増加は最小限です:#27432

これを今より詳しく見てみましょう。私が正しく理解していれば、プロットバックエンドが設定される方法は次のとおりです。

pd.set_option('plotting.backend', 'name_of_module')

したがって、私の理解では、次の作業を行いたい場合は次のようになります。

pd.set_option('plotting.backend', 'altair')

次に、 https://github.com/pandas-dev/pandas/blob/master/pandas/plotting/_core.pyですべての関数を定義するために、トップレベルのaltairパッケージが必要になり

私が正しく理解している場合、これは、matplotlibが現在ハードコーディングされている方法でパンダのaltairパッケージをハードコーディングせずに、 pd.set_option('plotting.backend', 'altair')正しく機能させる方法がないことを意味します、それは正しいですか?

https://github.com/pandas-dev/pandas/blob/f1b9fc1fab93caa59aebcc738eed7813d9bd92ee/pandas/ploting/_core.py#L1550 -L1551

もしそうなら、このAPIがサードパーティのパッケージで公開される手段を再考することを強くお勧めします。

私が提案する解決策は、エントリポイントベースのフレームワークを採用することです。たとえば、APIを実装するためにaltairエントリポイントを登録するaltair_pandasようなパッケージを作成できます。 そうしないと、ユーザーはpd.set_option('plotting.backend', 'altair')が期待どおりに機能しないことに永遠に混乱します。

同意しました。 エントリーポイントが進むべき道だと思います。 何かのプロトタイプを作ります。

2019年7月19日金曜日午後1時16分ジェイクヴァンデルプラス[email protected]
書きました:

今これをもっと詳しく見てください:私が正しく理解していれば、
プロットバックエンドが設定されるのは、以下を使用しています。

pd.set_option( 'ploting.backend'、 'name_of_module')

したがって、私の理解では、次の作業を行いたい場合は次のようになります。

pd.set_option( 'ploting.backend'、 'altair')

次に、すべての関数を定義するためのトップレベルのaltairパッケージが必要になります

https://github.com/pandas-dev/pandas/blob/master/pandas/ploting/_core.py。
Altairのトップレベルの名前空間をこれらすべてで汚染したくない
追加のAPI。 実際、私はaltairのパンダ拡張を
別のパッケージに住んでいるので、リリースのリズムに縛られていません
Altair自体。

私が正しく理解していれば、これはpd.set_option( 'ploting.backend'、
'altair')パンダでaltairパッケージをハードコーディングしなくても正しく動作します
matplotlibが現在ハードコーディングされている方法、それは正しいですか?

もしそうなら、私はこれがどのように可能になるかを再考することを強くお勧めします
サードパーティのパッケージ。 特に、エントリポイントベースのフレームワークを採用する
altairを登録するaltair_pandasのようなパッケージを作成させてください
エントリーポイント。 そうしないと、ユーザーはpd.set_option( 'ploting.backend'、
'altair')は彼らが期待することをしません。


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/pandas-dev/pandas/issues/26747?email_source=notifications&email_token=AAKAOITQM7HH5X4SZ4IAPS3QAIAIBA5CNFSM4HWIMEK2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJ
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAKAOISFLHDGXLGQ3PUMNLDQAIAIBANCNFSM4HWIMEKQ

あなたの言うことがほとんど正しい時期がありましたが、もはやそうではありません。

pandas.options.plotting.backend = 'altair'が必要な場合、0.25では関数altair.plot()です。 ある時点で、関数を単にplotではなくpandas_plotと呼ぶ方がよいと思ったので、他のものがあるバックエンドに固有でしたが、最終的には変更しませんでした。

altairのトップレベルでplot関数を作成することが問題になる場合は、将来のバージョンで名前を変更するか、 altair.pandas.plotを使用することもできますが、ユーザーはpandas.options.plotting.backend = 'altair.pandas'を設定する必要があります。

ユーザーがimport altair実行したら、オプションを自分で変更できます。 そして、バックエンドのレジストリを実装することができます。 しかし、ユーザーがpandas.options.plotting.backend = 'altair' 、それが失敗した場合、ユーザーimport altair以前に

最後に、altair(またはその他の視覚化ライブラリ)用に複数のパンダバックエンドを実装できる可能性があることを考慮してください。 したがって、私にとって、バックエンドの名前がaltairではないことは、必ずしも悪いことではありません。

これがエントリポイントベースの実装です

diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py
index 0610780ed..c8ac12901 100644
--- a/pandas/plotting/_core.py
+++ b/pandas/plotting/_core.py
@@ -1532,8 +1532,10 @@ class PlotAccessor(PandasObject):

         return self(kind="hexbin", x=x, y=y, C=C, **kwargs)

+_backends = {}

-def _get_plot_backend(backend=None):
+
+def _get_plot_backend(backend="matplotlib"):
     """
     Return the plotting backend to use (e.g. `pandas.plotting._matplotlib`).

@@ -1546,7 +1548,14 @@ def _get_plot_backend(backend=None):
     The backend is imported lazily, as matplotlib is a soft dependency, and
     pandas can be used without it being installed.
     """
-    backend_str = backend or pandas.get_option("plotting.backend")
-    if backend_str == "matplotlib":
-        backend_str = "pandas.plotting._matplotlib"
-    return importlib.import_module(backend_str)
+    import pkg_resources  # slow import. Delay
+    if backend in _backends:
+        return _backends[backend]
+
+    for entry_point in pkg_resources.iter_entry_points("pandas_plotting_backends"):
+        _backends[entry_point.name] = entry_point.load()
+
+    try:
+        return _backends[backend]
+    except KeyError:
+        raise ValueError("No backend {}".format(backend))
diff --git a/setup.py b/setup.py
index 53e12da53..d2c6b18b8 100755
--- a/setup.py
+++ b/setup.py
@@ -830,5 +830,10 @@ setup(
             "hypothesis>=3.58",
         ]
     },
+    entry_points={
+        "pandas_plotting_backends": [
+            "matplotlib = pandas:plotting._matplotlib",
+        ],
+    },
     **setuptools_kwargs
 )

なかなかいいと思います。 サードパーティのパッケージは、setup.py(またはpyproject.toml)を変更して次のようなものを含めます

entry_points={
    "pandas_plotting_backends": ["altair = pdvega._pandas_plotting_backend"]
}

ネーミングと実装の間の緊密な結合を壊すのが好きです。

私はエントリポイントを操作しませんでした、それらはPython環境のグローバルレジストリのようなものですか? 彼らに慣れていないので、私はそのアイデアが好きではありませんが、それはそれを行うための合理的な方法だと思います。

私はまだ両方のオプションが欲しいので、ユーザーがpandas.options.plottting.backend = 'my_own_project.my_custom_small_backend'実行すればそれは機能し、パッケージを作成したり、エントリポイントを設定したりする必要はありません。

私はエントリポイントを操作しませんでした、それらはPython環境のグローバルレジストリのようなものですか?

私も使ったことがありませんが、そういう考えだと思います。 私が理解していることから、それらはsetuptoolsからのものです(しかし、flitのようなパッケージはそれらにフックしますか?)。 したがって、これらは標準ライブラリの一部ではありませんが、setuptoolsはとにかく誰もが使用するものです。

私はまだ両方のオプションが欲しいです

import_module(backend_name)フォールバックするのは合理的なようです。

このページは役に立ちましたか?
0 / 5 - 0 評価