matplotlibのカラーマップ

オリジナルのカラーマップを作成して、matplotlibのプロットに使いたいときの方法です。

参考
qiita.com

やりたいことはすべてこちらの方に書いてあるのですが、あくまで備忘録用に書かせていただきます。
参考のColormapのカスタマイズのところで定義されているgenerate_cmap関数さえ書いてしまえば、あとはプロットするだけです。

と、解説すべてを丸投げにしてもいいのですが、さすがにこれでは剽窃となるので、オリジナリティを追加するためにもこちらのgenerate_cmap関数の内部でやってることに対しての自分なりの解釈を書かせていただきたいと思います。

まず、引数にはカラーマップに使う色をリスト形式で与えています。

次に、使う色のリストの長さを求めて、それのリストを作ります。
参考先では3つの色のリストを与えているので、values = [0, 1, 2]として処理されているはずです。

そしてnormalizationをした値と色のリストをタプルとし、それを新たな色のリストとして与えています。


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ここでいうnormalizationは最大値と最小値で規格化することを指します。
標準正規分布に変換することはstandardizationというようです。
日本語だとどちらも標準化と言われたりするようですが、英語では割りと区別して呼ばれているのかもしれません。
こういった点は英語のほうが便利だと思いますね。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
閑話休題
さてどういうことかを具体的に説明していきたいと思います。
参考先のサンプルを見ながら読んでみてください。

まず、vmaxはvaluesの最大値です。最小値は0です。
ですので、for文内のv/vmaxは規格化された値を出しているのだと思われます。
つまり、
color_list = [(0, mediumblue), (0.5, limegreen), (1.0, orangered)]
となっているはずです。
あとはこのcolor_listを基にmatplotlib.colorsのLinearSegmentedColormapが自動的に0, 0.5, 1.0以外の数値の色を補完してくれるので自動でカラーマップが作成されています。

2016/11/29 追記

もっと単純な書き方を思いついたので記しておきます。

from matplotlib.colors import LinearSegmentedColormap

def create_cmap(color_list = None):
    n = len(color_list)-1
    return LinearSegmentedColormap.from_list(name = 'custom', colors = [(i/n, j) for i, j in enumerate(color_list)])

np.dot

numpyの行列積を表すときにだいたいdotメソッドを使うと思いますが、先日読んだ記事ではpython3.5以降では@マークで行列積を表すことができるそうです。

>>> import numpy as np
>>> a = np.arange(0, 6).reshape(3, 2)
>>> a
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> b = np.arange(6, 10).reshape(2, 2)
>>> b
array([[6, 7],
       [8, 9]])
>>> a.dot(b)
array([[ 8,  9],
       [36, 41],
       [64, 73]])
>>> np.dot(a, b)
array([[ 8,  9],
       [36, 41],
       [64, 73]])
>>> a@b
array([[ 8,  9],
       [36, 41],
       [64, 73]])

上記の通り、すべて同じ結果になってますね。
dotメソッド自体は個人的には明示的に書かれていて、何をしているかわかりやすいと思うので、そんなに@を使うときがあるとは思えないですが、条件式の中に書く場合など、あまりごちゃごちゃさせたくないときは使いやすそうですね。

以下参考
neovisionconsulting.blogspot.jp

この記事は翻訳されたものですが、原文を書いている人はSebastian Raschkaという方でPython機械学習プログラミングという本を書かれている方です。アマゾンで検索していただけると割りと上の方に出てくる書籍だと思います。機械学習を学ぼうと思って、その本を読んでみましたが、完全に内容を理解できたわけではないですが、比較的わかりやすい本であったと思われます。ぜひ一度読んでみてください。

limitlessledその2

limitlessledの使い方です。

まず、limitlessledのpythonAPIであるledcontrollerをpipでインストールします。

limitlessledのブリッジのIPアドレスを調べます。あとはledcontrollerをimportして普通にpythonコードを書くだけです。

サンプルは以下です。

#IPアドレスは各環境で調べて、その値を文字列として渡します。
IPaddress = "192.168.xx.xx"

import ledcontroller as con

LED = con.LedController(IPaddress)

#LEDのon/off
LED.on()
LED.off()

'''
LEDの色調整
上から赤、オレンジ、緑をつけます。
三行目みたく第2引数に数字を与えてやると、2番グループに登録されている電球色のみ変えることができます。
'''
LED.set_color('red')
LED.set_color('orange')
LED.set_color('green', 2)

#LEDを白色に変える
#引数に数字を与えてやると、指定したグループに登録されている電球を白色にします。

LED.white()
LED.white(2)

そんなに難しい使い方ではないと思います。自分もまだ詳しくわかっているわけではないので、まだ複雑な使い方ができるかもしれません。

また、書き忘れていましたが、自分の環境はlimitlessled RGBWのwarm whiteバージョンです。

on/offをタイマーで設定してやりたかったので、今はpythonのtimeモジュールをインポートして自動消灯を可能にしています。CLIで操作するのも面倒なので、pyqtの練習がてらguiアプリも作って見たので、気が向いたら更新します。

参考にさせていただいたのは以下です。
takashiski.hatenablog.com

Limitlessled

去年の今頃に引っ越しをしまして、その当時照明に凝ってみようと考えていたこともあり、ワイヤレスで制御できるLEDを探していました。この分野で一番名前が売れているのは疑うまでもなくhueだと思いますが、いかんせん高いです。これは自分でも思いましたし、調べていたときいろいろなブログでも同じ考えを持っている人が多数いることがわかりました。そこで代案を調べているとLimitlessledという商品が浮上してきました。milight, easybulbという商品も中身は同じらしいです。そこでヤフオクでそこそこ安くLimitlessledを手に入れ、さらに4灯シーリングライトも買いました。Limitlessledの良い所としては、スマホアプリでの制御や、パソコンからWi-Fi経由での命令を送れること、また赤外線リモコン(別売)でも操作できることです。多様な操作方法があり、なおかつhueよりも安いということで、ネットでよく名前を見かけました。
しかし、マイナー商品であることに変わりはなく、スマホアプリは正直ダサいものしかなく、また当時プログラミングを知らない自分からすれば、パソコン経由からの操作もできませんでした。リモコンがあれば日常使いには問題がないのですが、リモコンもスマホアプリもタイマー設定がありませんでした。2時間程度のタイマーを設定しておいて寝てしまった後でも勝手に消灯してくれるというのが使いたかった機能の一つでもあるので、これは誤算でした。そこで前々から興味がありながらも、なにも勉強してこなかったプログラミングを学んでLimitlessledの操作をより幅広いものにしようという目的でプログラミングをはじめました。

ここまでが一年前の話です。
その後Pythonがわかりやすく解説してあるマイナビニュースの連載記事をもとにPythonを学び始め、それらの腕試し的にpaizaで問題を解き、ある程度Pythonを書けるようになった後、プログラミング言語の基礎的な言語であるC/C++を学びました。文法をある程度学んだぐらいで満足し、数ヶ月プログラミングから離れていた時期もあったのですが、googleのAlphaGoがニュースで話題になり、どうやら機械学習というプログラミングの分野があることを知り、それは今まで学んでいたPythonが使われていることが多いようだということを知り、再度プログラミングを学ぼうという気概が湧いてきたので、また学び始めたというのがここ一年でのプログラミングの勉強の経緯です。この間にもLinuxを通じてUNIX系OSの基礎的な考え方を学んだり、サイト構築のためにhtmlやcssを学んでみたりと、寄り道ばかりしていましたしまだまだ技術が未熟ではありますが、一年でここまで学べるものなのかとこの記事を書きながら驚いています。

まだまだ初心者の域を脱することはできていませんし、学ぶスピードも速い方ではないのでちょっとずつ前進していけたらいいなと思います。

なんていうことない話ではあるのですが、自分がプログラミングを始めたきっかけで、当初の目的でもあるled操作をようやっと修得することができたので、自分の中では少し感慨深いものがあったので記事を書かせて頂きました。

本当は経緯を簡単にまとめて、その後実際のサンプルコードを載せるつもりだったのですが、少し感傷にひたってしまってあまり書く気分ではなくなってしまいました。実際の操作方法は後日もう少し踏み込んだ内容も書けるようになってからにしたいと思います。

BIT演算

C/C++などのサイトでよく見るビット演算と言うものがどういうものかちょっとだけ分かってきたので、そのことについて書きます。

いままでビット演算はどのようにやっているのかそもそもよくわからなかったのですが、単純にint型の変数を宣言してその中に代入されている値を2進数で考えるということだけのようです。

例えば、

int x=1, y = 2, w = 4, z = 8;

と宣言すると、それぞれ2進数ではx = 0b0001, y = 0b0010, w = 0b0100, z = 0b1000と表せられます。(語頭の0bは2進数表記であることを表しています。)

このビット演算をif文の条件式の代わりとして使うことができます。

例えば、

#include <stdio.h>

#define BIT(x) 1 << (x)

typedef struct {
	int id;
	int height;
	int weight;
	int score;
} students;

int main(void) {
	students hanako = {1, 160, 52, 70};
	unsigned int id, height, weight, score;
	
	id     = BIT(0);
	height = BIT(1);
	weight = BIT(2);
	score  = BIT(3);

	printf("Press number for displaying info\n");
	printf("0: id, 1: height, 2: weight, 3: score\n>> ");
	unsigned int info, info_bi;
	scanf("%d", &info);

	info_bi = BIT(info);

	if(info_bi == id) {
		printf("id: %d\n", hanako.id);
	} else if(info_bi == height) {
		printf("height: %d\n", hanako.height);
	} else if (info_bi == weight) {
		printf("weight: %d\n", hanako.weight);
	} else if (info_bi == score) {
		printf("score: %d\n", hanako.score);
	}

	return 0;
}

このコードを実行すると、id, height, weight, scoreの内どの情報を表示しますかと聞いてくるので、見たい情報の番号を入力し、Enterを押すとhanakoの情報が表示されます。

これは簡単なプログラムですので、普通にif文を書いたほうが早いしわかりやすいと思いますが、複雑な論理演算の場合いろんな変数を宣言してそれらの論理演算を条件式に用いるより、スッキリした見た目になるのではないでしょうか。

正直あまり使うことはないかもしれませんが、学習の記録程度にまとめてみました。

非常に初歩的なこと

python環境の構築においてよく目にするPATHを通すということがどういうことかわかっていませんでした。
自分はどのディレクトリにおいてもコマンドにアクセスできるようにすることと理解しています。(初心者なので間違いがあれば訂正していただけると幸いです。)

自分はmacを使っているのですが、Macにはbashの設定ファイルである.bashrcやログイン時に設定を読み込む.bash_profileが設定されていません。それを自分で作成し、その中にPATHの設定項目を書くことで、いわゆるPATHをとおすということができるようになります。

恥ずかしながら、今までAnacondaを使っておきながら、.bashrcを設定していないため長らくPATHを通さず使ってきていました。

先程設定をしたため、ようやっとcondaコマンドを使えるようになりました。

ちなみにPATHはbash_profile内に書いておけばログイン時に読み込まれるそうで、.bashrc内に書く必要はないとのことです。
PATHの通し方等で参考になったサイトは以下です。
gist.github.com
qiita.com
oxynotes.com

np.whereの使い方

np.whereはnumpyに含まれる関数です。

np.where(condition, x, y)と引数を与えると、conditionが真の時にはx, conditionが偽の時にはyを与えるという風に使います。

違う使い方としては、np.where(condition)とだけすると、conditionが真の時のindexを返すようです。