damyarou

python, GMT などのプログラム

水路トンネル断面作図

2021.02.08投稿

概要

Python matplotlib による、水路トンネル断面作図プログラムを作りました。 スケールを比較するため、各種トンネルを並べて表示してあります。 並べ方は迷いましたが、結局 subplot で並べることにしました。

寸法用の矢印は barrow(両矢印)と sarrow (片矢印)で表示しています。 sarrow は、barrow<->-> に変えたものです。 両矢印では意識する必要はありませんが、片矢印では (x1, y1) が矢印の先端座標となることに注意。

コンクリート部は、以下に示すように、コンクリート外縁の内側をハッチングで塗りつぶした後、通水領域を白で塗りつぶし、コンクリートの外縁と内園に線を入れる処理で描いています。

plt.fill(xxo,yyo,color="#000000",fill=None,hatch='..')
plt.fill(xxi,yyi,color="#ffffff")
plt.plot(xxo,yyo,'-',color="#000000",lw=1)
plt.plot(xxi,yyi,'-',color="#000000",lw=1)

作例

プログラムでは2つの画像を作成するようになっていますが、作例として一方の例を示します。

f:id:damyarou:20210208065004j:plain

プログラム全文

# Typical cross section of power waterway
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tick


def barrow(x1,y1,x2,y2):
    col='#333333'
    arst='<->,head_width=3,head_length=10'
    aprop=dict(arrowstyle=arst,connectionstyle='arc3',facecolor=col,edgecolor=col,shrinkA=0,shrinkB=0,lw=1)
    plt.annotate('',
        xy=(x1,y1), xycoords='data',
        xytext=(x2,y2), textcoords='data', fontsize=0, arrowprops=aprop)


def sarrow(x1,y1,x2,y2):
    col='#333333'
    arst='->,head_width=3,head_length=10'
    aprop=dict(arrowstyle=arst,connectionstyle='arc3',facecolor=col,edgecolor=col,shrinkA=0,shrinkB=0,lw=1)
    plt.annotate('',
        xy=(x1,y1), xycoords='data',
        xytext=(x2,y2), textcoords='data', fontsize=0, arrowprops=aprop)


def annot1(dd,bb,hh,ds,dds,fsz):
    # additional lines for horizontal dimensions
    x1=-bb/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1=-dd/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1= dd/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1= bb/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    # additional lines for vertical dimensions
    x1=0; x2=-bb/2-ds; y1= hh/2; y2=y1; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1=0; x2=-bb/2-ds; y1= dd/2; y2=y1; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1=0; x2=-bb/2-ds; y1=-dd/2; y2=y1; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1=0; x2=-bb/2-ds; y1=-hh/2; y2=y1; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    # arrow lines for horizontal dimensions    
    x1=-bb/2; x2=x1-ds; y1=hh/2+ds-dds; y2=y1; sarrow(x1,y1,x2,y2)
    x1=-dd/2; x2=dd/2;  y1=hh/2+ds-dds; y2=y1; barrow(x1,y1,x2,y2)
    x1= bb/2; x2=x1+ds; y1=hh/2+ds-dds; y2=y1; sarrow(x1,y1,x2,y2)
    # arrow lines for vertical dimensions
    x1=-bb/2-ds+dds; x2=x1; y1= hh/2; y2=y1+ds; sarrow(x1,y1,x2,y2)
    x1=-bb/2-ds+dds; x2=x1; y1= dd/2; y2=-dd/2; barrow(x1,y1,x2,y2)
    x1=-bb/2-ds+dds; x2=x1; y1=-hh/2; y2=y1-ds; sarrow(x1,y1,x2,y2)
    # text fordimensions
    s1='{0:.0f}'.format(dd*1000)
    s2='{0:.0f}'.format((bb-dd)/2*1000)
    # horizontal dimensions
    xs=-(bb/2+dd/2)/2; ys=hh/2+ds-dds
    plt.text(xs,ys,s2,color='#000000',ha='center',va='bottom',fontsize=fsz)
    xs=0; ys=hh/2+ds-dds
    plt.text(xs,ys,s1,color='#000000',ha='center',va='bottom',fontsize=fsz)
    xs= (bb/2+dd/2)/2; ys=hh/2+ds-dds
    plt.text(xs,ys,s2,color='#000000',ha='center',va='bottom',fontsize=fsz)
    # vertical dimensions
    xs=-bb/2-ds+dds; ys=(hh/2+dd/2)/2
    plt.text(xs,ys,s2,color='#000000',ha='right',va='center',fontsize=fsz,rotation=90)
    xs=-bb/2-ds+dds; ys=0
    plt.text(xs,ys,s1,color='#000000',ha='right',va='center',fontsize=fsz,rotation=90)
    xs=-bb/2-ds+dds; ys=-(bb/2+dd/2)/2
    plt.text(xs,ys,s2,color='#000000',ha='right',va='center',fontsize=fsz,rotation=90)
    # angle
    x1=-bb/2-0.5; y1=0; x2=bb/2+0.5; y2=y1
    plt.plot([x1,x2],[y1,y2],'-.',color='#555555',lw=1)
    x1=0; y1=-hh/2-0.5; x2=x1; y2=hh/2+0.5    
    plt.plot([x1,x2],[y1,y2],'-.',color='#555555',lw=1)
    theta=np.radians(25)
    x1=bb/2*np.cos(theta); y1=-bb/2*np.sin(theta)
    plt.plot([-x1,0,x1],[y1,0,y1],'--',color='#555555',lw=1)
    xs=1; ys=-0.5
    plt.text(xs,ys,'25$^\circ$',ha='center',va='center',fontsize=fsz)


def annot2(dd,bb,ds,dds,fsz):
    hh=bb
    x1=-bb/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1=-dd/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1= dd/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    x1= bb/2; x2=x1; y1=0; y2=hh/2+ds; plt.plot([x1,x2],[y1,y2],'-',color='#000000',lw=1)
    
    x1=-bb/2; x2=x1-ds; y1=hh/2+ds-dds; y2=y1; sarrow(x1,y1,x2,y2)
    x1=-dd/2; x2=dd/2;  y1=hh/2+ds-dds; y2=y1; barrow(x1,y1,x2,y2)
    x1= bb/2; x2=x1+ds; y1=hh/2+ds-dds; y2=y1; sarrow(x1,y1,x2,y2)

    s1='{0:.0f}'.format(dd*1000)
    s2='{0:.0f}'.format((bb-dd)/2*1000)

    xs=-(bb/2+dd/2)/2; ys=hh/2+ds-dds
    plt.text(xs,ys,s2,color='#000000',ha='center',va='bottom',fontsize=fsz)
    xs=0; ys=hh/2+ds-dds
    plt.text(xs,ys,s1,color='#000000',ha='center',va='bottom',fontsize=fsz)
    xs= (bb/2+dd/2)/2; ys=hh/2+ds-dds
    plt.text(xs,ys,s2,color='#000000',ha='center',va='bottom',fontsize=fsz)

    x1=-bb/2-0.5; y1=0; x2=bb/2+0.5; y2=y1
    plt.plot([x1,x2],[y1,y2],'-.',color='#555555',lw=1)
    x1=0; y1=-hh/2-0.5; x2=x1; y2=hh/2+0.5    
    plt.plot([x1,x2],[y1,y2],'-.',color='#555555',lw=1)

    
def sec1(dd,bb,hh):
    # dd: internal diameter
    # bb: width of structure including concrete lining thickness
    # hh: height of structure including concrete lining thickness
    theta=np.radians(25)
    hd=hh-bb/2*(1+np.sin(theta))
    ww=bb-2*hd*np.tan(theta)   
    # outer line
    ang1=-theta
    ang2=np.pi+theta
    angl=np.linspace(ang1,ang2,num=230,endpoint=True)
    _xxo=bb/2*np.cos(angl)
    _yyo=bb/2*np.sin(angl)
    xxo=np.append(_xxo,[-ww/2,ww/2])
    yyo=np.append(_yyo,[-(hh-bb/2),-(hh-bb/2)])  
    # inner line
    angl=np.linspace(0,2*np.pi,num=360,endpoint=True)
    xxi=dd/2*np.cos(angl)
    yyi=dd/2*np.sin(angl)
    # drawing
    plt.fill(xxo,yyo,color="#000000",fill=None,hatch='..')
    plt.fill(xxi,yyi,color="#ffffff")
    plt.plot(xxo,yyo,'-',color="#000000",lw=1)
    plt.plot(xxi,yyi,'-',color="#000000",lw=1)


def circ(dd,bb):
    angl=np.linspace(0,2*np.pi,num=360,endpoint=True)
    xxo=bb/2*np.cos(angl)
    yyo=bb/2*np.sin(angl)
    xxi=dd/2*np.cos(angl)
    yyi=dd/2*np.sin(angl)
    plt.fill(xxo,yyo,color="#000000",fill=None,hatch='..')
    plt.fill(xxi,yyi,color="#ffffff")
    plt.plot(xxo,yyo,'-',color="#000000",lw=1)
    plt.plot(xxi,yyi,'-',color="#000000",lw=1)


def waterway_B(fsz,xmin,xmax,ymin,ymax):
    ds=1.0; dds=0.2
    plt.figure(figsize=(12,12),facecolor='w')
    plt.rcParams['font.size']=fsz
    plt.rcParams['font.family']='sans-serif'
    plt.subplots_adjust(wspace=0.1, hspace=0.1)

    plt.subplot(331)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    
    plt.subplot(332)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=7.7; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Headrace',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(333)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')

    plt.subplot(334)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=4.4; bb=dd+2*0.6
    circ(dd,bb)
    annot2(dd,bb,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Penstock (vertical shaft)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(335)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=4.4; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Penstock (horizontal)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(336)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=3.1; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Penstock (4 lanes)',ha='center',va='top',fontsize=fsz+2)
    
    plt.subplot(337)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=3.9; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Tailrace (4 lanes)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(338)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=5.5; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Tailrace (2 lanes)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(339)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')

    #plt.tight_layout()
    fnameF='fig_waterway_B.jpg'
    plt.savefig(fnameF, dpi=100, bbox_inches="tight", pad_inches=0.1)
    plt.show()

    
def waterway_J(fsz,xmin,xmax,ymin,ymax):
    ds=1.0; dds=0.2
    plt.figure(figsize=(12,12),facecolor='w')
    plt.rcParams['font.size']=fsz
    plt.rcParams['font.family']='sans-serif'
    plt.subplots_adjust(wspace=0.1, hspace=0.1)

    plt.subplot(331)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    
    plt.subplot(332)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=8.2; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Headrace',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(333)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')

    plt.subplot(334)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=4.7; bb=dd+2*0.6
    circ(dd,bb)
    annot2(dd,bb,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Penstock (vertical shaft)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(335)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=4.7; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Penstock (horizontal)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(336)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=3.3; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Penstock (4 lanes)',ha='center',va='top',fontsize=fsz+2)
    
    plt.subplot(337)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=4.1; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Tailrace (4 lanes)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(338)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=5.8; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Tailrace (2 lanes)',ha='center',va='top',fontsize=fsz+2)

    plt.subplot(339)
    plt.axis('off')
    plt.xlim([xmin,xmax])
    plt.ylim([ymin,ymax])
    plt.gca().set_aspect('equal',adjustable='box')
    dd=8.2; bb=dd+2*0.6; hh=dd+2*0.6
    sec1(dd,bb,hh)
    annot1(dd,bb,hh,ds,dds,fsz)
    plt.text(0,-bb/2-ds,'Tailrace (1 lane)',ha='center',va='top',fontsize=fsz+2)
    
    #plt.tight_layout()
    fnameF='fig_waterway_J.jpg'
    plt.savefig(fnameF, dpi=100, bbox_inches="tight", pad_inches=0.1)
    plt.show()


def main():
    fsz=12
    xmin=-6; xmax=6
    ymin=-6; ymax=6
    waterway_B(fsz,xmin,xmax,ymin,ymax)
    waterway_J(fsz,xmin,xmax,ymin,ymax)
    

#---------------
# Execute
#---------------
if __name__ == '__main__': main()

以 上