方法がエレガントであるかどうかは、いくぶん主観的です。私は個人的にあなたのアプローチが「matplotlib」の方法よりも優れていると思います。matplotlibのカラーモジュールから:
カラーマッピングには通常、2つのステップが含まれます。データ配列は、Normalizeまたはサブクラスのインスタンスを使用して最初に範囲0-1にマッピングされます。次に、0〜1の範囲のこの数値は、Colormapのサブクラスのインスタンスを使用して色にマップされます。
あなたの問題に関して私がこれから得たのは、Normalize
文字列を受け取り、それらを0-1にマップするサブクラスが必要であるということです。
Normalize
これは、から継承してサブクラスを作成する例ですTextNorm
。これは、文字列を0から1までの値に変換するために使用されます。この正規化は、対応する色を取得するために使用されます。
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
import numpy as np
from numpy import ma
class TextNorm(Normalize):
'''Map a list of text values to the float range 0-1'''
def __init__(self, textvals, clip=False):
self.clip = clip
# if you want, clean text here, for duplicate, sorting, etc
ltextvals = set(textvals)
self.N = len(ltextvals)
self.textmap = dict(
[(text, float(i)/(self.N-1)) for i, text in enumerate(ltextvals)])
self.vmin = 0
self.vmax = 1
def __call__(self, x, clip=None):
#Normally this would have a lot more to do with masking
ret = ma.asarray([self.textmap.get(xkey, -1) for xkey in x])
return ret
def inverse(self, value):
return ValueError("TextNorm is not invertible")
iris = np.recfromcsv("iris.csv")
norm = TextNorm(iris.field(4))
plt.scatter(iris.field(0), iris.field(1), c=norm(iris.field(4)), cmap='RdYlGn')
plt.savefig('textvals.png')
plt.show()
これにより、次のものが生成されます。

3種類のポイントを簡単に区別できるように、「RdYlGn」カラーマップを選択しました。いくつかの変更を加えることで可能ですが、このclip
機能をの一部として含めませんでした。__call__
従来、キーワードscatter
を使用してメソッドの正規化をテストできますが、キーワードをテストして文字列が格納されているかどうかを確認し、格納されている場合は、文字列値として色を渡していると想定します(例:「赤」、「青」)。 、など。したがって、呼び出しは失敗します。代わりに、で「操作」を使用して、0から1の範囲の値の配列を返します。norm
scatter
c
plt.scatter(iris.field(0), iris.field(1), c=iris.field(4), cmap='RdYlGn', norm=norm)
TextNorm
iris.field(4)
リストにないスティングに対しては、-1の値が返されることに注意してくださいtextvals
。これは、マスキングが役立つ場所です。