MEP9: グローバル インタラクション マネージャー#

アーティストとのすべてのユーザー インタラクションのグローバル マネージャーを追加します。ユーザーが望むように、任意のアーティストをサイズ変更可能、移動可能、強調表示可能、および選択可能にします。

ステータス番号

討論

ブランチとプルリクエスト#

https://github.com/dhyams/matplotlib/tree/MEP9

アブストラクト#

目標は、描画プログラムと非常によく似た方法で matplotlib アーティストと対話できるようにすることです。必要に応じて、ユーザーは既にキャンバス上にあるアーティストを移動、サイズ変更、または選択できる必要があります。もちろん、スクリプト ライターは、最終的にアーティストと対話できるかどうか、または静的であるかどうかを制御できます。

これを行うためのこのコードは、すでに非公開で実装およびテストされており、現在の「mixin」実装から matplotlib の真正な部分に移行する必要があります。

最終的に、matplotlib.artist.Artist で使用できる 4 つの新しいキーワード (_moveable_、_resizeable_、_selectable_、および _highlightable_) が得られます。これらのキーワードのいずれかを True に設定すると、そのアーティストのインタラクティブ性がアクティブになります。

実際、この MEP は matplotlib でのイベント処理の論理的な拡張です。matplotlib は、左マウス プレス、キー プレスなどの「低レベル」の操作を既にサポートしています。MEP は、サポートを論理レベルにまで拡張します。論理レベルでは、ユーザーからの特定のインタラクティブ ジェスチャが検出されたときに、アーティストに対してコールバックが実行されます。

詳細な説明#

この新しい機能は、エンドユーザーがグラフをより適切に操作できるようにするために使用されます。多くの場合、グラフはほとんどユーザーが望んでいるものですが、コンポーネントの位置やサイズを少し変更する必要があります。ユーザーにスクリプトに戻って場所を試行錯誤させるのではなく、単純なドラッグ アンド ドロップが適切です。

また、これは matplotlib を使用するアプリケーションをより適切にサポートします。ここでは、エンドユーザーは、プロットを微調整するために基になるソースを編集する合理的なアクセス権や欲求を持っていません。ここで、matplotlib が機能を提供する場合、キャンバス上のアーティストを必要に応じて移動またはサイズ変更できます。また、アプリケーションがそのようなことをサポートしている場合、ユーザーは (マウスオーバーで) アーティストを強調表示し、ダブルクリックで選択できる必要があります。この MEP では、強調表示と選択をネイティブでサポートしたいと考えています。アーティストが選択されたときに何が起こるかは、アプリケーション次第です。典型的な処理は、アーティストのプロパティを編集するためのダイアログを表示することです。

将来的には (これはこの MEP の一部ではありません)、matplotlib は、アーティストの選択時に発生する各アーティストのバックエンド固有のプロパティ ダイアログを提供する可能性があります。この MEP は、その種の機能に必要な足がかりになります。

現在、matplotlib にはいくつかのインタラクティブな機能 (legend.draggable() など) がありますが、それらは散在する傾向があり、すべてのアーティストが利用できるわけではありません。この MEP は、インタラクティブなインターフェイスを統一し、すべてのアーティストが利用できるようにすることを目指しています。

現在の MEP には、アーティストのサイズを変更するためのグラブ ハンドルと、アーティストが移動またはサイズ変更されたときに描画される適切なボックスも含まれています。

実装#

  • インタラクティビティ マネージャが、インタラクティビティ マネージャが処理する一貫したインターフェイスを持つように、アーティストの「ツリー」に適切なメソッドを追加します。対話機能をサポートする場合、アーティストに追加する提案された方法は次のとおりです。

    • get_pixel_position_ll(self): アーティストの境界ボックスの左下隅のピクセル位置を取得します

    • get_pixel_size(self): アーティストのバウンディング ボックスのサイズをピクセル単位で取得します

    • set_pixel_position_and_size(self,x,y,dx,dy): 指定された境界ボックス内に収まるように、アーティストの新しいサイズを設定します。

  • バックエンドに機能を追加して、1) 移動/サイズ変更を視覚的に示すために必要なカーソルを提供し、2) 現在のマウス位置を取得する機能を提供します。

  • マネージャーを実装します。これはすでに個人的に (dhyams によって) mixin として行われており、かなりのテストが行​​われています。目標は、マネージャーの機能をアーティストに移動して、現在コーディングしている「モンキーパッチ」としてではなく、matplotlib に適切に配置することです。

ミックスインの現在の概要#

(この mixin は今のところ単なるプライベート コードですが、明らかにブランチに追加できることに注意してください)

InteractiveArtistMixin:

mixin クラスを使用して、matplotlib キャンバスに描画された汎用オブジェクトを移動可能にし、場合によってはサイズ変更可能にします。パワーポイントのモデルに可能な限り忠実に従います。私が Powerpoint に夢中になっているからではなく、ほとんどの人が Powerpoint を理解しているからです。アーティストを選択可能にすることもできます。これは、アーティストがダブルクリックされたときに on_activated() コールバックを受け取ることを意味します。最後に、アーティストをハイライト可能にすることができます。これは、マウスが上を通過するたびにアーティストにハイライトが描画されることを意味します。通常、ハイライト可能なアーティストも選択可能になりますが、それはユーザーに任されています。したがって、基本的には、ユーザーがアーティストごとに設定できる 4 つの属性があります。

  • ハイライト可能

  • 選択可能

  • 可動

  • サイズ変更可能

移動可能 (ドラッグ可能) またはサイズ変更可能にするには、mixin のターゲットであるオブジェクトが次のプロトコルをサポートしている必要があります。

  • get_pixel_position_ll(self)

  • get_pixel_size(自己)

  • set_pixel_position_and_size(self,x,y,sx,sy)

サイズ変更不可能なオブジェクトは、sx および sy パラメータを自由に無視できることに注意してください。強調表示できるようにするには、ミックスインのターゲットであるオブジェクトが次のプロトコルもサポートしている必要があります。

  • get_highlight(自己)

ハイライトの描画に使用されるアーティストのリストを返します。

mixin のターゲットであるオブジェクトが matplotlib アーティストでない場合は、次のプロトコルも実装する必要があります。どこかに描かれているアーティストがいなければならないので、そうするのは通常かなり簡単です。通常、オブジェクトはこれらの呼び出しをそのアーティストにルーティングするだけです。

  • get_figure(自己)

  • get_axes(self)

  • 含む (自己、イベント)

  • set_animated(self,flag)

  • draw(self,renderer)

  • get_visible(自己)

次の通知がアーティストに対して呼び出され、アーティストはオプションでこれらを実装できます。

  • on_select_begin(self)

  • on_select_end(self)

  • on_drag_begin(self)

  • on_drag_end(self)

  • on_activated(self)

  • on_highlight(自己)

  • on_right_click(自己、イベント)

  • on_left_click(自己、イベント)

  • on_middle_click(自己、イベント)

  • on_context_click(自己、イベント)

  • on_key_up(自己、イベント)

  • on_key_down(自己、イベント)

インタラクティブなアーティストがイベントを処理しない場合、次の通知がキャンバスで呼び出されます。

  • on_press(自己、イベント)

  • on_left_click(自己、イベント)

  • on_middle_click(自己、イベント)

  • on_right_click(自己、イベント)

  • on_context_click(自己、イベント)

  • on_key_up(自己、イベント)

  • on_key_down(自己、イベント)

次の関数が存在する場合は、対話型オブジェクトの動作を変更するために使用できます。

  • press_filter(self,event) # オブジェクトがプレス イベントをルーティングするかどうかを決定します

  • handle_unpicked_cursor() # オブジェクトが選択解除されたときにカーソルがオブジェクト上を通過するときにカーソルを設定するためにオブジェクトで使用できます。

複数のキャンバスをサポートし、キャンバスごとにドラッグ ロック、モーション通知、およびグローバルな「有効」フラグを維持します。サイズ変更中にシフト キーを押したままにすることで、固定縦横比のサイズ変更をサポートします。

既知の問題:

  • 選択/ドラッグ操作中は Zorder に従いません。ブリット手法が使用されているため、これを修正できるとは思えません。私が考えることができる唯一の方法は、zorder が私よりも大きいすべてのアーティストを検索し、それらをすべてアニメーションに設定してから、ドラッグの更新ごとにすべてを一番上に再描画することです。これは非常に遅い場合があります。試す必要があります。

  • 1) カーソルがハードコードされている、2) wx.GetMousePosition() への呼び出しがある、という 2 つの理由により、ミックスインは wx バックエンドに対してのみ機能します。

下位互換性#

下位互換性に問題はありませんが、これが整ったら、既存のインタラクティブ関数 (legend.draggable() など) の一部を廃止することが適切です。

代替案#

私が知っているものはありません。