はじめに
最近は趣味でも仕事でも、計算はほとんどPythonで行っており、グラフ化もPython matplotlibで行っている。グラフには識別性を上げるため、色を使うことになるが、matplotlibの色一覧を手元においておきたいと思い、色一覧の画像を作成した。
作例
作り方
以下を参考にmatplotlibで扱える色一覧を取得する。辞書形式で色名および16進の値が取得できる。
あとはfill
を使って指定した矩形領域を塗りつぶしていくだけである。
しかし、グラフ作成時にこれを参照して色指定を行うためには、色名と16進の値をテキスト表示しておきたい。
そこで悩むのが、色名と16進のテキストの表示色である。一つ一つ指定してもいいのだが、なんとか自動で表示色を指定できないかということで、HSV値を使うことに。
私の場合、表示色指定には16進を用いているが、テキスト表示色を決めるため、16進の短冊色を一度RGBに変換し、さらにそれをHSVに変換し、その値に基づきテキスト表示色を決めるようにした。
テキスト表示色を決める関数(def penc())は以下の通り。colorsys.rgb_to_hsvという便利なものがあるので、RGBからHSVへの変換にはこれを使っている。
def penc(hval):
r=int(hval[1:3],16)
g=int(hval[3:5],16)
b=int(hval[6:8],16)
hsv=colorsys.rgb_to_hsv(r/255, g/255, b/255)
h=hsv[0]
s=hsv[1]
v=hsv[2]
col='#000000'
if 0.5<h: col='#ffffff'
if v<0.75: col='#ffffff'
return col
上の事例では、テキスト表示色をまず黒(#000000)に指定するが、HSVのHが0.5を超えた場合、およびVの値が0.75未満の場合は、テキスト表示色を白(#ffffff)にするようにしている。
反対色を使うなどの方法も考えたが、テキスト表示色を色とりどりにするのも抵抗があったため、表示色は黒と白のみで割り切るようにしたものである。
プログラム全文
import matplotlib
import colorsys
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['font.family'] = 'Ricty Diminished'
def penc(hval):
#https://docs.python.org/ja/3/library/colorsys.html
r=int(hval[1:3],16)
g=int(hval[3:5],16)
b=int(hval[6:8],16)
hsv=colorsys.rgb_to_hsv(r/255, g/255, b/255)
h=hsv[0]
s=hsv[1]
v=hsv[2]
col='#000000'
if 0.5<h: col='#ffffff'
if v<0.75: col='#ffffff'
return col
cdic=matplotlib.colors.cnames
lkey=[]
lval=[]
for key, val in zip(cdic.keys(), cdic.values()):
lkey=lkey+[key]
lval=lval+[val]
xmin=0
xmax=4
k=-1
fnameF='fig_col_mpl.png'
ymin=0
ymax=37
plt.figure(figsize=(6,12))
plt.xlim([xmin,xmax])
plt.ylim([ymax,ymin])
plt.axis('off')
fsize=8 # fontsize
k=-1
for i in range(int(ymin),int(ymax)):
for j in range(0,4):
k=k+1
if k<len(lval):
xs=float(j)
xe=xs+1.0
ys=float(i)
ye=ys+1.0
xx=[xs,xe,xe,xs]
yy=[ys,ys,ye,ye]
plt.fill(xx,yy,color=lval[k])
text1=lkey[k]
text2=lval[k]
xg=0.5*(xs+xe)
yg=0.5*(ys+ye)
col=penc(lval[k])
plt.text(xg,yg-0.25,text1,rotation=0,ha='center',va='center',fontsize=fsize,color=col)
plt.text(xg,yg+0.25,text2,rotation=0,ha='center',va='center',fontsize=fsize,color=col)
plt.savefig(fnameF, dpi=300, bbox_inches="tight", pad_inches=0)
以 上