web-dev-qa-db-ja.com

tab10のmatplotlib汎用カラーマップ

この質問は、SO( matplotlib-change-colormap-tab20-to-have-three-colors )からの質問に関連しています。

各色のアルファレベルを好きなだけステップで変更できるように、tab10カラーマップを微調整したいと思います。以下は、期待される出力が得られない例(3つのアルファレベルを持つ9色の場合)です。さらに、それは十分に一般的ではありません(if Elif staementsのため)。

どうすればそれができるのでしょうか?

この例では、3つのサブグループを持つ3つのグループがあります。

import pandas as pd
from matplotlib import pyplot as plt
import numpy as np

n_feature = 3
sub_feature = 3
col = []
for index in range(n_feature*sub_feature):
# loop over colors and change the last entry in descending order 3 times
        col.append(list(plt.cm.tab10(index)))

i = 0        
for item in col:
# loop over colors and change the last entry in descending order 3 times
    if i == 0:
        item[-1] = 0.9
        i+=1
    Elif i == 1:
        item[-1] = 0.7
        i+=1
    Elif i == 2:
        item[-1] = 0.5
        i = 0

gr = df.groupby(['a', 'a1'])

for index, item in enumerate(gr):
    name, val = item
    y = val.iloc[0,2:].values
    x = np.arange(len(y))
    plt.plot(x, y, '.-', color=col[index])

plt.show()

enter image description here

これはデータです:

{'a':{0: 'A'、1: 'A'、2: 'A'、3: 'B'、4: 'B'、5: 'B'、6: 'C'、7: 'C'、8: 'C'}、 'a1':{0:1、1:2:2:3、3:1、4:2、5:3、6:1、7:2、8: 3}、 'b':{0:1.0、1:5.0、2:9.0、3:1.5、4:5.5、5:9.5、6:1.75、7:5.75、8:9.75}、 'c':{ 0:2.0、1:6.0、2:10.0、3:2.5、4:6.5、5:10.5、6:2.75、7:6.75、8:10.75}、 'd':{0:3.0、1:7.0、 2:11.0、3:3.5、4:7.5、5:11.5、6:3.75、7:7.75、8:11.75}、 'e':{0:4.0、1:8.0、2:12.0、3:4.5、 4:8.5、5:12.5、6:4.75、7:8.75、8:12.75}}

7
Moritz

HSVシステムを使用して、同じ色相に対して異なる彩度と発光色を取得できます。最大10のカテゴリがあるとすると、tab10マップを使用して、特定の数の基本色を取得できます。それらの中から、サブカテゴリに明るい色合いをいくつか選択できます。

以下は関数categorical_cmapで、カテゴリの数(nc)とサブカテゴリの数(nsc)を入力として受け取り、nc*nscの異なる色のカラーマップを返します。同じ色相のnsc色があります。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors

def categorical_cmap(nc, nsc, cmap="tab10", continuous=False):
    if nc > plt.get_cmap(cmap).N:
        raise ValueError("Too many categories for colormap.")
    if continuous:
        ccolors = plt.get_cmap(cmap)(np.linspace(0,1,nc))
    else:
        ccolors = plt.get_cmap(cmap)(np.arange(nc, dtype=int))
    cols = np.zeros((nc*nsc, 3))
    for i, c in enumerate(ccolors):
        chsv = matplotlib.colors.rgb_to_hsv(c[:3])
        arhsv = np.tile(chsv,nsc).reshape(nsc,3)
        arhsv[:,1] = np.linspace(chsv[1],0.25,nsc)
        arhsv[:,2] = np.linspace(chsv[2],1,nsc)
        rgb = matplotlib.colors.hsv_to_rgb(arhsv)
        cols[i*nsc:(i+1)*nsc,:] = rgb       
    cmap = matplotlib.colors.ListedColormap(cols)
    return cmap

c1 = categorical_cmap(4, 3, cmap="tab10")
plt.scatter(np.arange(4*3),np.ones(4*3)+1, c=np.arange(4*3), s=180, cmap=c1)

c2 = categorical_cmap(2, 5, cmap="tab10")
plt.scatter(np.arange(10),np.ones(10), c=np.arange(10), s=180, cmap=c2)

c3 = categorical_cmap(5, 4, cmap="tab10")
plt.scatter(np.arange(20),np.ones(20)-1, c=np.arange(20), s=180, cmap=c3)    

plt.margins(y=0.3)
plt.xticks([])
plt.yticks([0,1,2],["(5, 4)", "(2, 5)", "(4, 3)"])
plt.show()

enter image description here