Matplotlib SVG ツールチップ

PythonPythonBeginner
オンラインで実践に進む

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、matplotlib のパッチにマウスオーバーしたときに表示されるツールチップを作成する方法についての手順を追ったチュートリアルです。matplotlib でツールチップを作成し、パッチにマウスオーバーしたときにその表示を切り替えるだけです。このアプローチは、事前にコードをもう少し多く書く代わりに、ツールチップの配置と外観を完全に制御できます。

VM のヒント

VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。

場合によっては、Jupyter Notebook が読み込み終わるまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。

学習中に問題がある場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。

パッチを作成する

まず、ツールチップが割り当てられるパッチを作成します。

rect1 = plt.Rectangle((10, -20), 10, 5, fc='blue')
rect2 = plt.Rectangle((-20, 15), 10, 5, fc='green')

shapes = [rect1, rect2]
labels = ['This is a blue rectangle.', 'This is a green rectangle']

パッチとツールチップの注釈を追加する

次に、パッチとツールチップの注釈をプロットに追加します。ツールチップの注釈は、annotate メソッドを使用して作成されます。xy パラメータをパッチの座標に設定し、xytext(0, 0) に設定して、ツールチップをパッチの真上に配置します。また、textcoords パラメータを 'offset points' に設定して、ツールチップをパッチに合わせて整列させます。color パラメータを 'w' に設定してテキストを白に、ha'center' に設定してテキストを水平方向に中央揃え、fontsize8 に設定してフォントサイズを設定し、bbox を設定してツールチップボックスのスタイルを設定します。

for i, (item, label) in enumerate(zip(shapes, labels)):
    patch = ax.add_patch(item)
    annotate = ax.annotate(labels[i], xy=item.get_xy(), xytext=(0, 0),
                           textcoords='offset points', color='w', ha='center',
                           fontsize=8, bbox=dict(boxstyle='round, pad=.5',
                                                 fc=(.1,.1,.1,.92),
                                                 ec=(1., 1., 1.), lw=1,
                                                 zorder=1))

    ax.add_patch(patch)
    patch.set_gid(f'mypatch_{i:03d}')
    annotate.set_gid(f'mytooltip_{i:03d}')

グラフを SVG 形式で保存する

BytesIO クラスと savefig メソッドを使って、グラフを偽のファイルオブジェクトに保存します。

ax.set_xlim(-30, 30)
ax.set_ylim(-30, 30)
ax.set_aspect('equal')

f = BytesIO()
plt.savefig(f, format="svg")

インタラクティビティを追加する

パッチにマウスオーバーしたときに表示と非表示が切り替わるツールチップを作成することで、プロットにインタラクティビティを追加します。これは、SVG ファイルから XML ツリーを作成し、ツールチップを非表示にし、パッチに onmouseoveronmouseout のコールバックを割り当てることで行います。また、パッチにマウスオーバーしたときに呼び出される ShowTooltipHideTooltip 関数も定義します。

tree, xmlid = ET.XMLID(f.getvalue())
tree.set('onload', 'init(event)')

for i in shapes:
    ## Get the index of the shape
    index = shapes.index(i)
    ## Hide the tooltips
    tooltip = xmlid[f'mytooltip_{index:03d}']
    tooltip.set('visibility', 'hidden')
    ## Assign onmouseover and onmouseout callbacks to patches.
    mypatch = xmlid[f'mypatch_{index:03d}']
    mypatch.set('onmouseover', "ShowTooltip(this)")
    mypatch.set('onmouseout', "HideTooltip(this)")

## This is the script defining the ShowTooltip and HideTooltip functions.
script = """
    <script type="text/ecmascript">
    <![CDATA[

    function init(event) {
        if ( window.svgDocument == null ) {
            svgDocument = event.target.ownerDocument;
            }
        }

    function ShowTooltip(obj) {
        var cur = obj.id.split("_")[1];
        var tip = svgDocument.getElementById('mytooltip_' + cur);
        tip.setAttribute('visibility', "visible")
        }

    function HideTooltip(obj) {
        var cur = obj.id.split("_")[1];
        var tip = svgDocument.getElementById('mytooltip_' + cur);
        tip.setAttribute('visibility', "hidden")
        }

    ]]>
    </script>
    """

## Insert the script at the top of the file and save it.
tree.insert(0, ET.XML(script))
ET.ElementTree(tree).write('svg_tooltip.svg')

まとめ

この実験では、matplotlib のパッチにマウスオーバーしたときに表示されるツールチップを作成する方法を学びました。matplotlib でツールチップを作成し、パッチにマウスオーバーしたときにその表示を切り替えるだけで済みました。また、パッチにマウスオーバーしたときに表示と非表示が切り替わるツールチップを作成することで、プロットにインタラクティビティを追加しました。