物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

Python: 斜視を矯正するための輻輳訓練カードを作るプログラミングコード

ある事情で、斜視を家庭で矯正訓練するための、円と線が書かれた紙(輻輳訓練カードと呼ばれるらしい)を作ったので、そのコードを公開します。

こういうの↓

import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.image as mpimg

inch2mm = 25.4 #25.4mm = 1inch

##--------------------------設定--------------------------##
width = 73/inch2mm #幅
steps = [40,67,70,70,40] # 境界線と円の中心、または円の中心同士の間隔 [mm]
steps = [step/inch2mm for step in steps] # mm -> inch
diameters = [5.2,7.1,11,17.5] # 円の半径 [mm] (手前から)
diameters = [diameter/inch2mm for diameter in diameters] # mm -> inch
colors = ["tab:red", "tab:orange", "yellow", "tab:blue"] # 円の色
images = [None, None, None, None, ] # 画像を表示しない場合は全てNoneにする
#画像を表示する場合はPATHを指定。透過画像が望ましい
# images = ['img_chara08-01.png', 'img_chara04-01.png', 'img_chara03-01.png', 'img_chara02-01.png'] 
##--------------------------設定--------------------------##

a4_width = 210 /inch2mm
a4_height = 297 / inch2mm
start = (a4_height-sum(steps))/2

fig, ax = plt.subplots(figsize=(a4_width, a4_height), dpi=300)
plt.subplots_adjust(left=0, right=1, top=1, bottom=0) #軸の上下左右のスペースを削除

for j in range(2):
    x = a4_width/2+width*(j-0.5)
    for i, d in enumerate(diameters):
        circle = plt.Circle((x, (start+sum(steps[:i+1]))), d/2, 
                            edgecolor='black' if images[i] is None else colors[i], 
                            facecolor=colors[i] if images[i] is None else "none", lw=1 if images[i] is None else 0.5) 
        ax.add_patch(circle) #円

        if images[i] is not None:
            img = mpimg.imread(images[i])
            ax.imshow(img, extent=((x-d/2), (x+d/2), (start+sum(steps[:i+1])-d/2), (start+sum(steps[:i+1])+d/2))) #画像
            
        if i>0:ax.plot([x,x],[(start+sum(steps[:i])+diameters[i-1]/2), (start+sum(steps[:i+1])-d/2)],color="black",lw=2) #円と円を結ぶ中央線

    ax.plot([x,x],[start, (start+steps[0]-diameters[0]/2)],color="black",lw=2) #境界線と円を結ぶ中央線
    ax.plot([x,x],[(a4_height-start), (start+sum(steps[:-1])+diameters[-1]/2)],color="black",lw=2) #境界線と円を結ぶ中央線
    
ax.plot([0,a4_width],[start,start],color="black",lw=0.1) #手前の境界線
ax.plot([0,a4_width],[(a4_height-start),(a4_height-start)],color="black",lw=0.1)  #奥の境界線
ax.plot([a4_width/2,a4_width/2],[0,a4_height],color="black",lw=0.1) #折り目
ax.plot([a4_width/2-width,a4_width/2-width],[0,a4_height],color="black",lw=0.1) #左側の折り目
ax.plot([a4_width/2+width,a4_width/2+width],[0,a4_height],color="black",lw=0.1) #右側の折り目

ax.set_xlim(0, a4_width)
ax.set_ylim(0, a4_height)
ax.axis('off')

pdf_path = "output.pdf" # 出力ファイル名
with PdfPages(pdf_path) as pdf:
    pdf.savefig(fig)
plt.show()

全てプログラミングコードで作っているので、円のサイズ、幅、線の幅、色を調整可能です。円の中に画像を埋め込むことも可能です。

画像を埋め込んでみた↓