カテゴリー

Plotly全般

【plotly&マーカー】plotlyのマーカーのシンボル

2021年4月6日

自作したplotlyのマーカーのシンボル一覧

こんな人にオススメ


plotlyにもmatplotlibのようにマーカー(シンボル)って存在しているの?あるならどんなものがあるのか知りたい!一覧で見せてほしい!

ということで、本記事ではplotlyのプロットで使用することができるマーカー(plotlyではsymbolという)の形状について説明する。plotlyの公式サイトには既に一覧はあるが、個人的にまとめた部分もあるのでぜひ見ていってほしい。

python環境は以下。

  • Python 3.9.2
  • plotly 4.14.3
  • plotly-orca 3.4.2

運営者のメガネとです。YouTubeTwitterInstagramも運営中。

自己紹介はこちらから、お問い合わせはこちらからお願いいたします。

運営者メガネ

シンボル一覧の出力

まずはどのようなシンボルがあるのかを出力する。

全配列を出力

以下のコードでplotlyのシンボルで指定可能な文字列の一覧を出力することができる。

raw_symbols = SymbolValidator().values
print(raw_symbols)
ここで、raw_symbolsにはint型の数字とstr型の数字と文字列があることがわかる。最初の数字2種類と次の文字列が同じシンボルを表す。イメージは以下。
        1. 0

       

        1. '0'

       

        1. 'circle'

       

       

 

    • 正方形
        1. 1

       

        1. '1'

       

        1. 'square'

       

       

 

0, '0', 'circle'のどの値を使用しても同じ円のシンボルを表すことができる。

公式サイトでグラフ化

plotlyの公式サイトの「Styling Markers in Python」でシンボルについての説明や例が載っている。そしてこのページの一番最後の「Custom Marker Symbols」ではシンボル一覧がグラフ化されている。以下にサイトに載っているコードを示す。

import plotly.graph_objects as go
from plotly.validators.scatter.marker import SymbolValidator

raw_symbols = SymbolValidator().values
namestems = []
namevariants = []
symbols = []
for i in range(0,len(raw_symbols),3):
    name = raw_symbols[i+2]
    symbols.append(raw_symbols[i])
    namestems.append(name.replace("-open", "").replace("-dot", ""))
    namevariants.append(name[len(namestems[-1]):])

fig = go.Figure(go.Scatter(mode="markers", x=namevariants, y=namestems, marker_symbol=symbols,
                           marker_line_color="midnightblue", marker_color="lightskyblue",
                           marker_line_width=2, marker_size=15,
                           hovertemplate="name: %{y}%{x}<br>number: %{marker.symbol}<extra></extra>"))
fig.update_layout(title="Mouse over symbols for name & number!",
                  xaxis_range=[-1,4], yaxis_range=[len(set(namestems)),-1],
                  margin=dict(b=0,r=0), xaxis_side="top", height=1400, width=400)
fig.show()

このブログでは使用しない、箱にどんどん入れていくスタイルの書き方。執筆者流に書き換えたのが以下。

import sys
import plotly
import plotly.io as pio
import plotly.graph_objects as go
from plotly.validators.scatter.marker import SymbolValidator

# このファイルの2つ上の階層にplotlyのlayoutテンプレートがある
sys.path.append('../../')
from plotly_layout_template import *
import plotly_layout_template as template

# グラフ保存のpath指定
pio.orca.config.executable = ('/Applications/orca.app/Contents/MacOS/orca')

# plotlyのシンボル一覧
raw_symbols = SymbolValidator().values
def official_graph():
    """plotlyの公式サイトに記載されているmarkerのシンボル一覧をグラフ化
    """

    # 各シンボルの大枠の名称
    namestems = []
    # 各シンボルの付加要素(塗りつぶしか塗らないか塗りつぶしドットか塗りつぶさないドットか)
    namevariants = []
    # シンボルを表す数字
    symbols = []

    for i in range(0, len(raw_symbols), 3):
        name = raw_symbols[i + 2]
        symbols.append(raw_symbols[i])
        # circleとcircle-openは大枠ではcircleなので-openを削除。dotも同様
        namestems.append(name.replace("-open", "").replace("-dot", ""))
        # シンボルの名称から大枠の部分の文字列を削除して付加要素のみを抽出
        namevariants.append(name[len(namestems[-1]):])

    plot = []
    d = go.Scatter(
        mode="markers",
        x=namevariants, y=namestems,
        marker=dict(
            symbol=symbols, color="lightskyblue", size=15,
            line=dict(color="midnightblue", width=2),
        ),
        hovertemplate="name: %{y}%{x}<br>number:"
        + "%{marker.symbol}<extra></extra>"
    )
    plot.append(d)

    layout = go.Layout(
        height=1400, width=400,
        title=dict(
            text="Mouse over symbols for name & number!",
        ),
        xaxis=dict(
            range=[-1, 4],
        ),
        xaxis_side="top",
        yaxis=dict(
            range=[len(set(namestems)), -1],
        ),
        margin=dict(b=0, r=0),
    )

    fig = go.Figure(data=plot, layout=layout)
    plotly.offline.iplot(fig)

    # 作成したグラフを保存
    pio.write_html(
        fig,
        "plotly-symbol_plotly_official.html", auto_open=False
    )
    # このままグラフを保存するとなぜか横長のグラフになってしまう
    # pio.write_image(fig, "plotly-symbol_plotly_official.png")

official_graph()

なぜかこのコードで画像を保存するとpngファイルが横長になる。どうすれば解決できそうか大体は見当がついているが、とりあえずは先に書くことを優先する。これでできるグラフが以下。

plotly公式サイトでのマーカーシンボル一覧

plotly公式サイトでのマーカーシンボル一覧

横軸が無名のシンボルが塗りつぶしに該当し、-openが塗りつぶさない、-dotが塗りつぶして中心に点を打った、-open-dotが塗りつぶさない中心に点を打ったシンボルに該当する。なお、バッテンを表すx-thinなどには塗りつぶす場所がないので-open-dotの機能は付与されていない。

自己流のグラフ化

上述の公式サイトでのグラフがとても見やすいのでこれでも十分だが、あまりにも縦長すぎると感じた。ここでは横長にしつつ一覧性を保つコードを書いたので紹介する。plotlyのレイアウトテンプレートについては以下参照。

def graph(columns: int):
    """plotlyのマーカー一覧をグラフ化

    Parameters
    ----------
    columns : int
        グラフの列数指定
    """

    # intだけ抽出
    int_symbol = [x for x in raw_symbols if type(x) is int]
    # 文字列だけ抽出
    str_symbol = [x for x in raw_symbols if not str(x).isdecimal()]

    plot = []
    for num, symbols in enumerate(str_symbol):
        d = go.Scatter(
            mode="markers",
            # xは切り捨て、yは約数でで場所をずらしている
            x=[num // columns], y=[num % columns],
            name=symbols,
            marker=dict(
                symbol=symbols, color="lightskyblue", size=15,
                line=dict(color="midnightblue", width=2),
            ),
            hoverlabel=dict(
                font=dict(
                    family='Times New Roman', size=15
                )
            ),
            hovertemplate=f"{symbols}<br>{int_symbol[num]}",
            + "<extra></extra>",
            # プロットをグループ化
            legendgroup=num // columns,
        )
        plot.append(d)

    layout = go.Layout(
        template=template.plotly_layout(),
        title=dict(
            text="Mouse over symbols for name & number!",
        ),
        xaxis=dict(
            range=[-1, len(str_symbol) / columns],
        ),
        xaxis_side="top",
        yaxis=dict(
            range=[columns, -1],
        ),
        # 凡例のグループを横に並べる
        legend=dict(orientation='h'),
    )

    fig = go.Figure(data=plot, layout=layout)
    plotly.offline.iplot(fig)

    # 作成したグラフを保存
    pio.write_html(
        fig,
        "plotly-symbol_plotly.html", auto_open=False
    )
    pio.write_image(fig, "plotly-symbol_plotly.png")

graph(
    columns=16
)

このコードではcolumnsを指定することで表示列数を変更することができる。今は16にしているので16列のグラフとなる。
また、int_symbolでシンボルの中で数字のものだけ、str_symbolでシンボルの中でシンボル名のものだけを引っ張ってきた。グラフのx, yはそれぞれraw_symbolsの各要素の番号(何番目の要素か)を

  • x: 16で割った時の商 = 要素の値が16の倍数になるまでは同じ値
  • y: 16で割った時の余り = 0から15の間

というふうに設定することで綺麗に並ぶように設定している。完成したグラフは以下。

自作したplotlyのマーカーのシンボル一覧

自作したplotlyのマーカーのシンボル一覧

ここで、新規キャラとしてlegendgroupという変数が出てくる。この変数はプロットをグループ化するというもので、凡例を表示・非表示する時にグループで同時に行うというもの。これを使用することで凡例をまとめることができる反面、個々で凡例を表示・非表示にすることが出来なくなる。
では、なぜこの変数を使用したのかというとplotlyの凡例は列数を変更することができないから。legendgroupを使用することでグループごとにまとめられて中途半端に改行された凡例ではなくなる。今回は各グループが1列に対応する。

HTML表示

上記のグラフをHTML表示したものが以下。今回は情報量が多いので、グラフをレスポンシブ対応にしたら凝縮されてしまった。凡例は途切れる部分がスクロールできるように変更されている。ありがてぇ。


工夫次第でオリジナルなシンボルができる

plotlyのシンボルは塗りつぶし有無やドット有無がある。これを自分で塗りつぶしだけ使用したり、塗りつぶしと塗りつぶしなしとを使用したりとすれば自由自在にグラフを作ることができる。是非とも色々といじってほしい。

スイッチボット

2022/9/11

【SwitchBotロックレビュー】これからのスタンダードになりうるスマートロック

こんな人にオススメ SwitchBotからスマートロック「SwitchBotロック」が発売された ...

生活に役立つ

2022/10/25

【メガネ厳選】クソ便利に使っているサービスやアイテム達

このページでは執筆者「メガネ」が実際に使って便利だと感じているサ ...

マウス

2022/9/11

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

完全ワイヤレスイヤホン(TWS)

2022/11/21

【ながら聴きイヤホン比較】SONY LinkBuds、ambie、BoCoはどれがおすすめ?

こんな人におすすめ 耳を塞がない開放型のイヤホンに完全ワイヤレスӟ ...

macOSアプリケーション

2022/10/15

【M1 Mac】MacBook Proに入れている便利でニッチなアプリを21個紹介する

こんな人におすすめ MacBookを購入してLINEとか必要最低限のアプリは入れた。 ...

完全ワイヤレスイヤホン(TWS)

2022/10/23

【SENNHEISER MOMENTUM True Wireless 3レビュー】高レベルでバランス型の高音質イヤホン

こんな人におすすめ SENNHEISER MOMENTUM True Wireless 3って実際のところどうなの? 評判は良い ...

完全ワイヤレスイヤホン(TWS)

2022/11/21

【SONY WF-1000XM4レビュー】神とゴミのハーフ&ハーフ

こんな人におすすめ SONYのフラグシップモデル「SONY WF-1000XM4」ってどれくらい性 ...

完全ワイヤレスイヤホン(TWS)

2022/8/19

【Nothing ear (1)レビュー】ライトな完成度、アップデートに期待

こんな人にオススメ 完全ワイヤレスイヤホン(TWS)でスケルトンボディ ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

ベンチャー企業のWebエンジニア駆け出し。独学のPythonで天文学系の大学院を修了→新卒を1.5年で辞める→転職→今に至る。
常時金欠のガジェット好きでM1 MacBook Pro x Galaxy S22 Ultraの狂人。
人見知りで根暗だったけど、人生楽しもうと思って良い方向に狂う→人生が楽しい

ガジェットのレビューとPythonコードを記事にしています。ぜひ楽しんでください🦊
自己紹介と半生→変わって楽しいの繰り返し

-Plotly全般
-, , ,