damyarou

python, GMT などのプログラム

matplotlib 数表を伴うグラフ

記事の最後に行く

ポイント

数表を伴うグラフを作ってみました。数表の重要性が高いとき、グラフの横についている方が便利なので。

描画領域を分割指定

以下のように plt.axes により、画像全体を左70%、右30%に分け、左側にグラフ、右側に表を描画しています。

plt.axes((0.0, 0.0, 0.7, 1.0)); drawfig1(_el,_vv,fsz) # 左側にグラフを作成
plt.axes((0.7, 0.0, 0.3, 1.0)); drawfig2(str1,str2,fsz) # 右側に表を作成

白抜き記号描画

以下は白抜き丸を表示するコマンドです。

    plt.plot(_vv/1e6,_el,
             marker='o',
             markersize=8,
             markeredgecolor='#000000', # markerの縁を黒色に指定
             markerfacecolor='#ffffff', # markerの内部を白色に指定
             markeredgewidth=2, # markerの縁の線の太さを指定
             clip_on=False) # markerを枠線の外に描画することを許容(実際には枠線上プロットを許容)

枠内に文字列を描画

以下により、枠内に文字列を描画します。使用する枠の特性は prop に書き込み、bbox=prop で枠の特性を指定します。

    props = dict(boxstyle='round', facecolor='#ffffff', alpha=1)
    xs=xmin+0.95*(xmax-xmin); ys=ymin+0.05*(ymax-ymin)
    plt.text(xs,ys, textstr, fontsize=fsz,va='bottom',ha='right', bbox=props)

描画結果

f:id:damyarou:20190501172946p:plain

プログラム

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tick
from scipy import interpolate


def drawfig1(_el,_vv,fsz):
    xmin=0.0;xmax=16.0;dx=1.0
    ymin=48.0;ymax=78.0;dy=2.0
    plt.xlabel('Volume ($\\times 10^6\: m^3$)')
    plt.ylabel('Elevation (EL.m)')
    plt.xlim(xmin,xmax)
    plt.ylim(ymin,ymax)
    plt.xticks(np.arange(xmin,xmax+dx,dx))
    plt.yticks(np.arange(ymin,ymax+dy,dy))
    plt.gca().xaxis.set_minor_locator(tick.MultipleLocator(dx/2))
    plt.gca().yaxis.set_minor_locator(tick.MultipleLocator(dy/2))
    plt.grid(which='both',color='#999999',linestyle='solid')
    plt.plot([xmin,xmax],[60,60],color='#ff0000')
    plt.plot([xmin,xmax],[68,68],color='#ff0000')
    plt.text(11.5,60.1,'MOL (EL.60.00)',color='#ff0000',ha='left',va='bottom',fontsize=fsz)
    plt.text(11.5,68.1,'FSL (EL.68.00)',color='#ff0000',ha='left',va='bottom',fontsize=fsz)
    plt.plot(_vv/1e6,_el,'-',color='#000000',lw=2,clip_on=False)
    plt.plot(_vv/1e6,_el,
             marker='o',
             markersize=8,
             markeredgecolor='#000000',
             markerfacecolor='#ffffff',
             markeredgewidth=2,
             clip_on=False)
    # Text drawing in a box
    s_gross=_vv[8]/1e6
    s_effec=(_vv[8]-_vv[3])/1e6
    s1='Gross storage     : {0:4.2f} mil.m$^3$'.format(s_gross)
    s2='Effective storage : {0:4.2f} mil.m$^3$'.format(s_effec)
    textstr=s1+'\n'+s2
    props = dict(boxstyle='round', facecolor='#ffffff', alpha=1)
    xs=xmin+0.95*(xmax-xmin); ys=ymin+0.05*(ymax-ymin)
    plt.text(xs,ys, textstr, fontsize=fsz,va='bottom',ha='right', bbox=props)


def drawfig2(str1,str2,fsz):
    xmin=0; xmax=5
    ymin=0; ymax=len(str1)
    plt.axis('off')
    plt.xlim(xmin,xmax)
    plt.ylim(ymin,ymax)
    for i in range(len(str2)):
        if len(str2)-2<=i:
            plt.text(1.0,i+0.2,str1[i],ha='center',va='bottom',fontsize=fsz)
            plt.text(3.5,i+0.2,str2[i],ha='center',va='bottom',fontsize=fsz)
        else:
            plt.text(xmin+0.5,i+0.2,str1[i],ha='left',va='bottom',fontsize=fsz)
            plt.text(xmax-0.5,i+0.2,str2[i],ha='right',va='bottom',fontsize=fsz)
    seqy=np.array([ymax,ymax-2,ymin])
    seqx=np.array([2])
    plt.hlines(seqy, xmin+0.3, xmax-0.3, colors="k", linestyle="solid")
    plt.vlines(seqx, ymin, ymax, colors="k", linestyle="solid")


def figcontrol(_el,_vv,str1,str2):
    fsz=16
    fnameF='fig_RHV.png'
    fig=plt.figure(figsize=(10,6),facecolor='w')
    plt.rcParams["font.size"] = fsz
    plt.rcParams['font.family'] ='sans-serif'
    plt.axes((0.0, 0.0, 0.7, 1.0)); drawfig1(_el,_vv,fsz)
    plt.axes((0.7, 0.0, 0.3, 1.0)); drawfig2(str1,str2,fsz)
    plt.savefig(fnameF, dpi=200, bbox_inches="tight", pad_inches=0.1)
    plt.show()


def main():
    # latest (28 August 2017)
    _el=np.array([48,58,59,60,61,62,64,66,68,70,72,74,76])
    _vv=np.array([0,10138,33792,106516,826754,1621125,3359842,5239851,7223138,9396419,11083948,13273548,15852459])
    # linear interpolation with elevation interval of 0.5m
    f=interpolate.interp1d(_el,_vv)
    el=np.arange(48,76+0.5,0.5)
    vv=f(el)
    # makeing list for table drawing
    str1=[]
    str2=[]
    for i in range(0,len(_el)):
        str1=str1+['{0:6.1f}'.format(_el[i])]
        str2=str2+['{0:,}'.format(_vv[i])]
    str1=str1+['(m)']
    str2=str2+['Volume (m$^3$)']
    str1=str1+['EL.']
    str2=str2+['Cumulative']
    # data saving for other programs
    fnameW='inp_RHV.txt'
    fw=open(fnameW,'w')
    print('{0}'.format(1),file=fw)
    for i in range(0,len(el)):
        print('{0:6.1f}{1:12.0f}'.format(el[i],vv[i]),file=fw)
    fw.close()
    # figure control    
    figcontrol(_el,_vv,str1,str2)


#==============
# Execution
#==============
if __name__ == '__main__': main()

Thank you.

記事の先頭に行く