Python♪提出資料で使えるmatplotlibグラフ書式例1

matplotlibのグラフ出力結果を使いたいけれどExcelのような表現ができず、面倒になって結局Excelを使ってしまう。というのは「あるある」だと思います。そこで、実際に提出資料として使える書式例を紹介したいと思います。

1.グラフの出力例

さっそくグラフの出力例を見てみましょう。私自身が最低限必要と感じる書式を盛り込んだ例です。「あ~、これこれ」と思った方は、書式例のコードをコピペして自由に使ってください。

結果を見れば簡単なのですが、一苦労でした。

matplotlibグラフ出力例1

2.私が必要と感じる書式

私がmatplotlibのグラフを使う上で必要と考えた内容を箇条書きにしました。

  • タイトル、X軸ラベル、Y軸ラベル、凡例で日本語を使用
  • マーカー、ラインの色、線幅、線種の設定
  • マーカーの中の色を透明に設定できる
  • 主目盛、補助目盛の色、線幅、線種の設定
  • タイトル、ラベルなどで上付文字、下付文字の使用
  • 凡例の位置、書式の設定
  • タイトルの位置の変更
  • テキストの背景色を白に設定(グラフ目盛り線との重なりを避ける)
  • タイトルの背景色を白に設定(グラフ内にタイトルを表示する場合)
  • グラフの縦と横の長さの比率を調整
  • x軸y軸の値を10のN乗表記に設定
  • x軸y軸で表示する小数点の桁数を指定
  • 画像データ保存時の背景を透明に設定(貼付時に他との干渉を少なくする)
  • 画像データの解像度を指定

なお、x軸y軸の値を10のN乗で表記する方法については、以下の記事を参考にさせていただきました。わかりやすい記事で大変参考になります。

MatplotlibのY軸の目盛りを指数表記(10のN乗表記)に変更する

3.グラフ表示の2種類の書式

matlotlibのグラフを表示する上で情報が混乱するのは「Matlabスタイル」と「オブジェクト指向スタイル」の2種類があることです。「Matlabスタイル」の方がシンプルですが、「オブジェクト指向スタイル」は複数のグラフを並べて表示することができるので、提出資料としてmatplotlibを使用する方はオブジェクト指向スタイルに慣れておいた方が便利だと思います。

詳細な説明は行いませんが、簡単にコードの違いを紹介したいと思います。

(1) Matlabスタイル

コード01は「Matlabスタイル」のコードです。リストやnumpy配列のデータをplt.plot()の引数として渡すだけで、グラフとして視覚化してくれるため手軽で便利です。

#コード01
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 4, 7, 8, 3]
plt.plot(x, y)
plt.show()

以下、出力グラフです

(2) オブジェクト指向スタイル

コード02は「オブジェクト指向スタイル」です。実はそれほど記述が増えるわけではありません。ただ、6行目で変数figと変数axにそれぞれfigureオブジェクト、axesオブジェクトを代入するところが、なじみにくいだけです。出力結果はコード01と同じです。

figureオブジェクトの中に複数のaxesオブジェクトを表示することが可能なので、グラフを並べる表示に対応することができます。

#コード02
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 4, 7, 8, 3]
#変数figにfigureオブジェクトを代入、変数axにaxesオブジェクトを代入
fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()

なお、複数のaxesオブジェクトを表示したサンプルコードは以下の記事で紹介しています。

Python♪提出資料で使えるmatplotlibグラフ書式例2

4.サンプルコード

コード03は最初に紹介したグラフのサンプルコードです。各コマンドの詳しい説明はしませんが、コードの中にコマンドの説明がありますので、すぐに自分用にアレンジできると思います。

なお、タイトルやラベルで日本語を表示するにはPCの中のフォントを指定する必要があります。自分のPCのどこにフォントがあるのかを探して位置とファイル名を指定してください。サンプルコードでは40、42行目でフォントを指定しています。MSゴシックはmsgothic.ttc、MS明朝はmsmincho.ttcです。

#コード03 (2020.5.16) by Snow Tree in June
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties #日本語表示
import matplotlib.ticker as mtick #軸の値の書式設定
from matplotlib.ticker import ScalarFormatter #軸の値の10のN乗表記

class FixedOrderFormatter(ScalarFormatter):
    '''任意の桁数で軸の値の10のN乗表記するために必要なクラス

    (1) import必要
       from matplotlib.ticker import ScalarFormatter
    (2) 参照サイト
      http://villageofsound.hatenadiary.jp/entry/2014/11/06/155824
    '''
    def __init__(self, order_of_mag=0, useOffset=True, useMathText=True):
        self._order_of_mag = order_of_mag
        ScalarFormatter.__init__(self, useOffset=useOffset, 
                                 useMathText=useMathText)
    def _set_orderOfMagnitude(self, range):
        self.orderOfMagnitude = self._order_of_mag

def main_graph(t, a1, a2, a3):
    '''matplotlibによる散布図描画プログラム(グラフ数:3)
    
    t:時間(s)
    a1, a2, a3:加速度(m/s2)
    '''

    #figuree, axesオブジェクトの生成
    #figureオブジェクトの内側に複数のaxesオブジェクトを表示可能
    #figsize(x, y) アスペクト比を指定
    fig, ax = plt.subplots(figsize=(6, 4))

    #日本語表示のためのフォント
    # 自分のPCの中でフォントファイルが保存されている場所を指定する必要がある
    #  msgothic.ttc: MSゴシック
    #  msmincho.ttc: MS明朝
    #MSゴシック、フォントサイズ40 (タイトル、軸ラベル等のフォントサイズは後で変更可能)
    fp1 = FontProperties(fname='C:/Windows/Fonts/msgothic.ttc',size=40) 
    #MSゴシック、フォントサイズ16 (凡例のフォント)
    fp2 = FontProperties(fname='C:/Windows/Fonts/msgothic.ttc',size=16)
    
    #背景、境界の色、幅指定のフォーマット(タイトル、軸ラベル、テキストで使用可)
    boxdic1 = {
    'facecolor' : 'white',
    'edgecolor' : 'black',
    'linewidth' : 1
    }


    #グラフ化するデータと基本設定
    ax.plot(t, a1, '-D',
            color='k', linestyle='-',
            markersize=5, markerfacecolor='None',
            markeredgecolor='k', markeredgewidth=1.0,
            label = '標準')
    ax.plot(t, a2, '-^',
             color='k',linestyle='--', linewidth=1.0,
             markersize=5,
             markeredgecolor='k',
             label = '高速')
    ax.plot(t, a3, '-o',
             color='r', linestyle='-', linewidth=1.0,
             markersize=5, markerfacecolor='None',
             markeredgecolor='r',
             label = '低速')
    
    #主目盛の設定
    #xmin:x軸の主目盛の開始位置、xmax:x軸の主目盛の終了位置
    #つまり、主目盛はxminからスタートし、xmaxで終わる。
    #xstep:x軸の主目盛の間隔。
    #
    #なお、ax.set_xticks(np.linspace(xmin, xmax, n_x))とは
    #xmin~xmaxの範囲を(n_x - 1)分割した位置に主目盛を表示する。
    #したがって、(xmax - xmin)/xstep が整数になるような値を指定しなければ、
    #想定通りの目盛を表示できない。
    #
    #xmin~xmaxは実際にグラフで表示する範囲よりも大きめに設定しないと、
    #目盛が表示されない範囲ができてしまう。
    #
    #np.arange()は、stepが小数の場合、目盛の最後の数値が表示されないことが
    # あるため、np.linspace()で主目盛の位置を指定する。
    xmin = 0 #必ず主目盛を表示する値を指定
    xmax = 6 #必ず主目盛を表示する値を指定
    ymin = -1500 #必ず主目盛を表示する値を指定
    ymax = 1500 #必ず主目盛を表示する値を指定
    xstep = 1
    ystep = 500
    n_x = int((xmax - xmin) / xstep) + 1
    n_y = int((ymax - ymin) / ystep) + 1
    ax.set_xticks(np.linspace(xmin, xmax, n_x))
    ax.set_yticks(np.linspace(ymin, ymax, n_y))

    #補助目盛の設定
    xstep = 0.2  #x軸補助メモリのピッチ
    ystep = 100  #y軸補助メモリのピッチ
    n_x = int((xmax - xmin) / xstep) + 1
    n_y = int((ymax - ymin) / ystep) + 1
    ax.set_xticks(np.linspace(xmin, xmax, n_x),
                  minor = 'True')
    ax.set_yticks(np.linspace(ymin, ymax, n_y),
                  minor = 'True')

    #目盛の書式
    #which: 主目盛と補助目盛の選択('major', 'minor', 'both')
    #axis: 目盛を設定する軸('x', 'y', 'both')
    #direction: 目盛の方向 ('in', 'out', 'inout')
    #bottom, top, left, right 下、上、左、右のメモリ表示のon, off
    ax.tick_params(which='both', axis='both', direction='in',
               bottom='on', top='off', left='on', right='off')

    #主目盛線の書式
    ax.grid(which='major',color='black',
            linestyle='--', linewidth=0.5) 

    #補助目盛線の書式
    ax.grid(which='minor',color='black',
            linestyle='--', linewidth=0.3) 

    #グラフで表示する範囲を設定 ※目盛の設定の後に記述する必要あり
    ax.set_xlim(0, 6) #x軸範囲
    ax.set_ylim(-1100, 1100) #y軸範囲

    #-----(軸目盛の数値の書式設定)------
    #y軸の値を10のN乗表記にする
    #「class FixedOrderFormatter」が必要
    n10 = 2 #10のN乗のNを指定
    ax.yaxis.set_major_formatter(FixedOrderFormatter(n10,
                                    useMathText=True))
    ax.ticklabel_format(style='sci',  axis='y',scilimits=(0, 0))

    #x軸の値を少数第1位まで表示する
    #  その他の書式指定
    #    例1: %表示にする場合は  '%.1f%%'
    #    例2: π表示  '%.0fπ'
    fmt = '%.1f'
    #「import matplotlib.ticker as mtick」が必要
    xticks = mtick.FormatStrFormatter(fmt)
    ax.xaxis.set_major_formatter(xticks)

    #指数表示部分のフォントサイズ
    ax.yaxis.offsetText.set_fontsize(16)

    #x軸y軸の数値のフォントサイズ  
    ax.tick_params(labelsize = 16)
    #-------------------------------------------
    
    #タイトル、x軸ラベル、y軸ラベル内の上付、下付
    #$^{●}$ →「●」の部分を上付
    #$_●$  →「●」の部分を下付


    #タイトル
    # x = 1, y= 1  タイトルの位置を指定(タイトルの位置は割合で指定する)
    ax.set_title('図-1 時間と加速度の関係', fontproperties = fp1,
                 fontsize=18 ,x = 0.5, y= -0.5)

    #x軸、y軸ラベル
    #2の上付:「$^{2}$」
    ax.set_xlabel('時間(s)', fontproperties = fp1, fontsize=18)
    ax.set_ylabel('加速度(m/s$^{2}$)', fontproperties = fp1,
                  fontsize=18)

    #テキスト(テキストの位置は座標で指定する)
    #xの下付: 「$_x$」
    ax.text(4.7, -950,'Case:R$_x$', fontproperties = fp1,
            fontsize=18, bbox = boxdic1)
    
    #凡例の表示(フォントのサイズはfp2の中で設定)
    # loc = 'center' 凡例の基準点からの位置
    #   'upper left', 'upper right', 'lower left',
    #   'lower right', 'center left', 'center right',
    #   'upper center', 'lower center', 'center',
    #   'best', 'right'
    # bbox_to_anchor=(0.5, 0.5) 凡例の基準位置(マイナスも可能)
    # prop 凡例の日本語フォント指定(このフォントの中でフォントサイズも指定)
    # ncol 凡例の列数
    # frameon=False  枠を中の塗りつぶしごとなくす
    # framealpha=0.5 凡例の透明度
    # facecolor=[0.,0.,0.] 凡例の色(0~1)で指定
    # edgecolor=[0.,0.,0.] 凡例の枠の色(0~1)で指定
    # markerscale = 1 凡例のマーカーの大きさ(同じ大きさなら1)
    # 以下、凡例の全体の大きさを調整する
    #   borderpad: 凡例の枠とラベルのスペース。
    #   labelspacing: ラベルの行間のスペース。
    #   columnspacing: 列が2列以上のとき、列の間のスペース。
    #   handlelength: ハンドル(ライン)の長さ。
    #   handletextpad: ハンドルとラベルのスペース。
    ax.legend(loc = 'center', bbox_to_anchor=(0.5, -0.3),
              ncol = 3, prop = fp2, edgecolor=[0.,0.,0.])
    
    #画像ファイルの保存 ※plt.show()の前に記述
    # 第1引数:保存ファイル名
    # format = 'png' フォーマット形式
    # transparent = True 背景透明
    # dpi = 300 解像度
    # bbox_inches='tight' を入れると画像が切れない
    plt.savefig('グラフ出力画像.png', format = 'png',
                 transparent = False, dpi = 300, bbox_inches='tight')

    plt.show()
    
if __name__ == '__main__':

    #-----(グラフ化するデータ)------
    t = np.linspace(0, 2 * np.pi, 20)
    A = 1000
    w = 1
    a = 2
    a1 = -w ** 2 * A *np.cos(w * t - a)
    A = 1000
    w = 0.8
    a = 0
    a2 = -w ** 2 * A *np.cos(w * t - a)
    A = 500
    w = 1.4
    a = -1
    a3 = -w ** 2 * A *np.cos(w * t - a)
    #----------------------------

    #グラフ描画
    main_graph(t, a1, a2, a3)

私が実際に購入した教材のご紹介

以下、私が実際に購入したPythonの教材をまとめてみました。 Pythonを学習する上で、少しでもお役に立つことができればうれしいです。

Python♪私が購入したPythonの書籍のレビュー
UdemyのPythonの動画講座を書籍を買う感覚で購入してみた

その他

Twitterへのリンクです。SNSもはじめました♪

以下、私が光回線を導入した時の記事一覧です。
 (1) 2020年「光回線は値段で選ぶ」では後悔する ←宅内工事の状況も説明しています。
 (2) NURO光の開通までWiFiルーターを格安レンタルできる
 (3) NURO光の屋外工事の状況をご紹介。その日に開通!
 (4) 光回線開通!実測するとNURO光はやっぱり速かった
 (5) ネット上のNURO光紹介特典は個人情報がもれないの?