たくさんデータがあるとき、matplotlibで普通にプロットすると大変見づらいです。
配布資料にするにも、自分でデータから傾向を読み取るにも不便です。
なのでグラデーションにしたくなります。
#やったこと
numpy.linspace みたいにグラデーションを作れる関数を作りました。
使い方
- gradation 関数をコピペ
- カラーコード(sRGB)をググって、start, endに入れます。
- return がsRGBの文字列のリストになっています。
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def gradation(start="#CCCCCC", end="#00519A", step=5):
"""
before use it
import numpy as np
return like this:
['#cccccc', '#bc9aa8', '#b95ba9', '#8b2aa9', '#370e83']
"""
from colorsys import rgb_to_hls, hls_to_rgb
if len(start) != 7 or len(end) != 7:
raise Exception(
f"argument length must be 7: now{len(start)}, {len(end)}")
rgb_s = (int(start[i:i + 2], 16) / 256 for i in range(1, 4))
rgb_e = (int(end[i:i + 2], 16) / 256 for i in range(1, 4))
hls_s = np.array(rgb_to_hls(*rgb_s))
hls_e = np.array(rgb_to_hls(*rgb_e))
diff_hls = hls_e - hls_s
# color is circle
diff_hls[0] = (diff_hls[0] + 0.5) - np.floor(diff_hls[0] + 0.5) - 0.5
hls_list = [hls_s + diff_hls * i / step for i in range(step)]
rgb_list = [hls_to_rgb(*p) for p in hls_list]
# Transeform floor rgb to Strings rgb
str_rgb = []
for rgb in rgb_list:
str_rgb.append(
f"#{int(rgb[0]* 256):02x}{int(rgb[1]* 256):02x}{int(rgb[2]* 256):02x}")
return str_rgb
def main():
nsinx = 5
x = np.linspace(0, np.pi * 4, 100)
dx = np.pi / (nsinx)
sinxes = [np.sin(x - i * dx) for i in range(nsinx)]
gra = gradation(start="#CCCCCC", end="#00519A", step=nsinx)
for i, sinx in enumerate(sinxes):
plt.plot(x, sinx, label=f"dx*{i}", lw=3, color=gra[i])
plt.legend()
plt.show()
if __name__ == "__main__":
main()
追記
関数内でのimportなどPEP8に準拠してません。
コピペで簡単に使えるようにするためです。
コピペコーディングスタイルは保守性がまるでだめです
なんとかしたいが、パッケージングするほどでもないので
なんかいいアイデアあったら教えてもしいです
#参考文献
大変参考になりました。
ありがとうございます。
Python でグラデーション中の色を求める