カテゴリー

当サイトはアフィリエイトプログラムによる収益を得ています〈景品表示法に基づく表記です)

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

ガジェット

2023/9/18

【デスクツアー2022下半期】モノは少なく、でも効率的に Desk Updating #0

今回はガジェットブロガーなのにデスク環境を構築していない執筆者の ...

ライフハック

2023/9/16

【Audible vs YouTube Premium】耳で聴く音声学習コンテンツを比較

ワイヤレスイヤホンが普及し耳で学習することへのハードルが格段に下 ...

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

2023/9/18

【SENNHEISER MOMENTUM True Wireless 3レビュー】全てが整ったイヤホン

今回は高音質・高機能なSENNHEISERのフラグシップ完全ワイヤレスイヤホン「SENNH ...

ライフハック

2023/3/11

【YouTube Premiumとは】メリットしかないから全員入れ

今回はYouTube Premiumを実際に使ってみてどうなのか、どんなメリット/デメリット ...

マウス

2023/8/17

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

ベストバイ

2023/9/18

【ベストバイ2022】今年買って良かったモノのトップ10

2022年ベストバイ この1年を振り返って執筆者は何を買ったのか。ガジェッ& ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/9/16

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

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

macOSアプリケーション

2022/9/30

【Chrome拡張機能】便利で効率的に作業できるおすすめの拡張機能を18個紹介する

こんな人におすすめ Chromeの拡張機能を入れたいけど、調べても同じような ...

macOSアプリケーション

2023/5/3

【Automator活用術】Macで生産性を上げる作業の自動化術

今回はMacに標準でインストールされているアプリ「Automator」を使ってできる ...

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

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

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

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

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

  • この記事を書いた人

メガネ

Webエンジニア駆け出し。独学のPythonで天文学系の大学院を修了。常時金欠のガジェット好きでM2 Pro MacBook Pro(30万円) x Galaxy S22 Ultra(17万円)使いの狂人。自己紹介と半生→変わって楽しいの繰り返しレビュー依頼など→お問い合わせ運営者情報、TwitterX@m_ten_pa、 YouTube@megatenpa、 Threads@megatenpa

-Plotly全般
-, , , ,