カテゴリー

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

plt

【plt&マーカー一覧】matplotlibのマーカーをグラフ化

2021年10月7日

こんな人にオススメ

matplotlib.pyplotpltのマーカーにはどんな種類があるの?

三角とか四角とか色んなマーカーを使ってみたい。

ということで、今回はpltのマーカー一覧をグラフ化して見やすくする。pltのマーカーの種類なんて腐るほどの記事が挙がっているけど、自分用の備忘録としても記録しておく。

なお、plotlyでも以下の記事で同じようにマーカー一覧をグラフ化している。

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

続きを見る

python環境は以下。

  • Python 3.9.7
  • numpy 1.21.2
  • matplotlib 3.4.3

運営者のメガネです。YouTubeTwitterInstagramも運営中。自己紹介お問い合わせページあります。

運営者メガネ

作成したコード全文

下準備

import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib
from matplotlib.lines import Line2D

sys.path.append('../../')
import plt_layout_template
plt.ioff()

まずは下準備としてのimport関連。今回はマーカーを自動で取得するのでmatplotlib関連が多め。plt_layout_templateは自作のテンプレートで、これをimportしておくだけでキレイなグラフが描ける。

plt.rcParamsでデフォルトを変更した後のグラフ
【pltテンプレート】matplotlib.pyplotのグラフ作成テンプレート

続きを見る

また、plt.ioff()はVisual Studio Codeの拡張機能「Code Runner」を使用するために設定。デフォルトではioff()になっているけど、テンプレートでion()にしているから設定している。

ion()のままだとCode Runnerの実行でグラフが表示されない。保存するだけならion()のままでも問題ない。

pltのマーカー一覧を文字で

markers = Line2D.markers
print(markers)
# {'.': 'point', ',': 'pixel', 'o': 'circle', 'v': 'triangle_down', '^': 'triangle_up', '<': 'triangle_left', '>': 'triangle_right', '1': 'tri_down', '2': 'tri_up', '3': 'tri_left', '4': 'tri_right', '8': 'octagon', 's': 'square', 'p': 'pentagon', '*': 'star', 'h': 'hexagon1', 'H': 'hexagon2', '+': 'plus', 'x': 'x', 'D': 'diamond', 'd': 'thin_diamond', '|': 'vline', '_': 'hline', 'P': 'plus_filled', 'X': 'x_filled', 0: 'tickleft', 1: 'tickright', 2: 'tickup', 3: 'tickdown', 4: 'caretleft', 5: 'caretright', 6: 'caretup', 7: 'caretdown', 8: 'caretleftbase', 9: 'caretrightbase', 10: 'caretupbase', 11: 'caretdownbase', 'None': 'nothing', None: 'nothing', ' ': 'nothing', '': 'nothing'}

ということで、pltのマーカー一覧を表示すると上のようになる。出力はdictkeysの表現とvaluesの表現、どちらで指定しても指定した記号の表現となる。

見づらいのでforで回して表示してみる。

for marker in markers.items():
    print(marker)
# ('.', 'point')
# (',', 'pixel')
# ('o', 'circle')
# ('v', 'triangle_down')
# ('^', 'triangle_up')
# ('<', 'triangle_left')
# ('>', 'triangle_right')
# ('1', 'tri_down')
# ('2', 'tri_up')
# ('3', 'tri_left')
# ('4', 'tri_right')
# ('8', 'octagon')
# ('s', 'square')
# ('p', 'pentagon')
# ('*', 'star')
# ('h', 'hexagon1')
# ('H', 'hexagon2')
# ('+', 'plus')
# ('x', 'x')
# ('D', 'diamond')
# ('d', 'thin_diamond')
# ('|', 'vline')
# ('_', 'hline')
# ('P', 'plus_filled')
# ('X', 'x_filled')
# (0, 'tickleft')
# (1, 'tickright')
# (2, 'tickup')
# (3, 'tickdown')
# (4, 'caretleft')
# (5, 'caretright')
# (6, 'caretup')
# (7, 'caretdown')
# (8, 'caretleftbase')
# (9, 'caretrightbase')
# (10, 'caretupbase')
# (11, 'caretdownbase')
# ('None', 'nothing')
# (None, 'nothing')
# (' ', 'nothing')
# ('', 'nothing')

マーカーは5種類

実はマーカーは大きく分けると5種類ある。詳しくは公式の「matplotlib.markers」に書いてあるけど、リストにすると以下。

  1. 「o」や「s」など規定の記号
  2. 「$...$」で囲んだ$\LaTeX$表現
  3. 座標を指定して線でつなぐ(verts)
  4. matplotlib.path.Pathで作成できる図形
  5. (numsides, num, angle)の形式で作成できる図形

一般的なサイトには1, 2が書かれている事多いし、実際に1と2で大半のマーカーはできると思う。

さっきのfor文での出力は1に該当する。2の$\LaTeX$形式は自作する形になるので以下で追加しておく。

markers['$\\\\alpha$'] = 'alpha'  # アルファ
markers['$\\\\times$'] = 'multiplication'  # 掛け算記号
markers[r'$\\sum_{k=1}^n k^2$'] = 'sum'  # シグマ記号

追加分も含めた出力は以下。

for marker in markers.items():
    print(marker)
# ('.', 'point')
# (',', 'pixel')
# ('o', 'circle')
# ('v', 'triangle_down')
# ('^', 'triangle_up')
# ('<', 'triangle_left')
# ('>', 'triangle_right')
# ('1', 'tri_down')
# ('2', 'tri_up')
# ('3', 'tri_left')
# ('4', 'tri_right')
# ('8', 'octagon')
# ('s', 'square')
# ('p', 'pentagon')
# ('*', 'star')
# ('h', 'hexagon1')
# ('H', 'hexagon2')
# ('+', 'plus')
# ('x', 'x')
# ('D', 'diamond')
# ('d', 'thin_diamond')
# ('|', 'vline')
# ('_', 'hline')
# ('P', 'plus_filled')
# ('X', 'x_filled')
# (0, 'tickleft')
# (1, 'tickright')
# (2, 'tickup')
# (3, 'tickdown')
# (4, 'caretleft')
# (5, 'caretright')
# (6, 'caretup')
# (7, 'caretdown')
# (8, 'caretleftbase')
# (9, 'caretrightbase')
# (10, 'caretupbase')
# (11, 'caretdownbase')
# ('None', 'nothing')
# (None, 'nothing')
# (' ', 'nothing')
# ('', 'nothing')
# ('$\\\\alpha$', 'alpha')
# ('$\\\\times$', 'multiplication')
# ('$\\\\sum_{k=1}^n k^2$', 'sum')

規定のマーカーとLaTeX表現をグラフ化

まずは規定のマーカーと$\LaTeX$表現について。変数markersにこれらの情報は入れてあるので、あとはグラフ化するのみ。

左上から下に向かってマーカーが表現され、全体の半分の数まできたら右上に移動して再度、下方向に並んで行くようにした。

プロットの左にあるのがプロットで使用した記号で、その名称をプロットの上に傾けて表現した。右下の$\LaTeX$はごちゃごちゃして見づらい。

def graph():
    fig, ax = plt.subplots(1, 1, figsize=(16, 10))
    ax.set_axis_off()  # 軸を非表示に
    fig.tight_layout()  # 余白を小さく
    ax.set_title('Line2D.markers')

    for num, (symbol, name) in enumerate(markers.items()):
        length = len(markers)
        half = length // 2

        color = cm.jet(num / length)  # 色を作成

        x = np.array((1, 2, 3)) + (num // half) * 3  # 左から右に並ぶように
        y = np.array((1, 2, 3)) - num % half  # 上から下に並ぶように

        ax.plot(x, y, marker=symbol, ms=15, color=color)
        # グラフにテキストを追加
        ax.text(min(x), min(y), f"{symbol}    ", ha='right', va='center')
        ax.text(min(x), min(y), name, ha='left', va='bottom', rotation=10)

    fig.savefig('default_latex.png')
    plt.show()

graph()

3列にしたい場合はhalfの部分を//3にすればいい。ただし、数が偶数なので3列からちょっとはみ出て4列になってしまう。そこは調節してほしい。

また、左上から下方向に作成したが、xy//%を入れ替えて調節すると左上から右へ1つ行ってすぐに左下に行くようにもできる。

verts, Path, numsidesのグラフ化のための関数

def graph_from_dct(title, dct, save_name):
    fig, ax = plt.subplots(1, 1, figsize=(16, 10))
    ax.set_axis_off()  # 軸を非表示に
    fig.tight_layout()  # 余白を小さく
    ax.set_title(title)

    # 入力したdictで回してグラフ化
    for num, (name, val) in enumerate(dct.items()):
        x = np.array((1, 2, 3))
        y = np.array((1, 2, 3)) - num

        ax.plot(x, y, marker=val, ms=15, color='black')
        ax.text(min(x), min(y), f"    {name}", ha='left', va='top')

    fig.savefig(save_name)
    plt.show()

続いては残りの3項目、verts, Path, numsidesについて。これらについてはmarkersと一緒にしてもよかったけど、場合分けとして分けた。

大体のサイトだとこのverts, Path, numsidesの解説がない。ここでも深くまではやらないけど、こんなこともできるんだくらいに見てほしい。

graph_from_dct関数ではマーカーをdictで指定して、それを1マーカーずつズラしながらプロットするというもの。あとはテキストをいい感じに追加した。

vertsをグラフ化

ということで、まずはvertsからグラフ化する。vertsは(x, y)の形式で座標を指定することで、この座標に従ってプロットされるというもの。

座標の設定をうまくすることで色んな図形を作成することができる。上だと三角形とタグのようなものをグラフにしてみた。

指定した座標を直線でつなぐので、曲線を使用する図形はマーカーにはできないが、簡単なものはこれで作成可能。

verts_dct = {
    'triangle': ((-1, -1), (1, -1), (1, 1), (-1, -1)),
    'tag': [[-1, -1], [1, -1], [1, 1], [-1, 1], [-2, 0]],
}
graph_from_dct(title='verts', dct=verts_dct, save_name='verts')

pathをグラフ化

続いてはpath。こちらはmatplotlib.path.Pathから指定される図形を示す。詳細は公式サイトに載っているが、具体的にプロットしたのが上。

パックマンっぽいのとカマボコ状のもの、そして円形をプロットしてみた。まあ円のmarkerを指定したい時は普通にcircleにすればいい。

path_dct = {
    'Pac-Man': matplotlib.path.Path.wedge(90, 0),
    'kamaboko': matplotlib.path.Path.arc(theta1=0, theta2=180),
    'circle': matplotlib.path.Path.circle(center=(8, 0), radius=5),
}
graph_from_dct(title='path', dct=path_dct, save_name='path')

numsidesをグラフ化

最後はnumsidesを指定してグラフ化。これは3つの数字で図形を作成するというもの。各数字はtuple(numsides, 0, angle)のように指定する。

  • numsides: エッジの個数
  • 第二引数
    • 0: 多角形
    • 1: 星に近い図形
    • 2: アスタリスク
  • angle: 回転させる角度

同じnumsides=8でも第二引数が1か2かで塗りつぶしがあるかないかが異なったりする。一部はtri_upなどの記号で指定したのと同じになる。

しかし、もうちょっと複雑な図形にしようとするとこのnumsidesは使えるだろう。

numsides_dct = {
    '1-0-30': (1, 0, 30),
    '3-0-0': (3, 0, 0),
    '3-0-30': (3, 0, 30),
    '8-0-30': (8, 0, 0),

    '1-1-30': (1, 1, 30),
    '3-1-0': (3, 1, 0),
    '3-1-30': (3, 1, 30),
    '8-1-30': (8, 1, 0),

    '1-2-30': (1, 2, 30),
    '3-2-0': (3, 2, 0),
    '3-2-30': (3, 2, 30),
    '8-2-30': (8, 2, 0),
}
graph_from_dct(title='numsides', dct=numsides_dct, save_name='numsides')

ちょっと深掘ると新しい世界

ということで、今回はpltを使用して色々なマーカーを見てきた。既に書いたけど、大体のサイトだと基本的なマーカーしか紹介していない。

しかし、今回のようにもうちょっと深掘りをしてみると他の方法も見えてきて結構面白い。

また何かの機会にちょっと深掘りをするような記事を作成してみたい。

関連記事

【plotly&go.Scatter】plotlyの散布図グラフの描き方

続きを見る

【plt vs plotly】matplotlibとgoでグラフの比較

続きを見る

【plt&subplot】pythonのpltで複数グラフを1つの画像に描く

続きを見る

【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

-plt
-, ,