カテゴリー

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
スポンサーリンク
スポンサーリンク

運営者のメガネです。TwitterInstagramも運営してます。

自己紹介はこちらから、お問い合わせはこちら。

運営者メガネ

作成したコード全文

下準備

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&コッホ曲線】フラクタル図形の雪の結晶をスライダーで作成してみる

続きを見る

関連コンテンツ

スポンサーリンク

Amazonのお買い物で損したない人へ

1回のチャージ金額通常会員プライム会員
¥90,000〜2.0%2.5%
¥40,000〜1.5%2.0%
¥20,000〜1.0%1.5%
¥5,000〜0.5%1.0%

Amazonギフト券にチャージすることでお得にお買い物できる。通常のAmazon会員なら最大2.0%、プライム会員なら2.5%還元なのでバカにならない。

ゲットしたポイントは通常のAmazonでのお買い物に使えるからお得だ。一度チャージしてしまえば、好きなタイミングでお買いものできる。

なお、有効期限は10年だから安心だ。いつでも気軽にAmazonでお買い物できる。

Amazonチャージはここから出来るで

もっとお得なAmazon Prime会員はこちらから

30日間無料登録

執筆者も便利に使わせてもらってる

スポンサーリンク

  • この記事を書いた人

メガネ

独学でpythonを学び天文学系の大学院を修了。 ガジェット好きでMac×Android使い。色んなスマホやイヤホンを購入したいけどお金がなさすぎて困窮中。 元々、人見知りで根暗だったけど、人生楽しもうと思って良い方向に狂ったために今も人生めちゃくちゃ楽しい。 pythonとガジェットをメインにブログを書いていますので、興味を持たれましたらちょこちょこ訪問してくだされば幸いです🥰。 自己紹介→変わって楽しいの繰り返し

-plt
-, ,