乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

可視化

はいどうも

また錯視です。


動画はこちら



今回は
色違いに見えるボールを
描いてみましょう。

まずはライブラリを用意します。
from PIL import Image, ImageDraw, ImageFilter

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

次にソースはこちら


plt.figure(figsize=(16,9))
size ,c_y,c_v = (320, 320),(255, 241, 0),(170, 68, 153)
im1,im2 = Image.new("RGB", size, color=c_y),Image.new("RGB", size, color=c_v)
dst = Image.new('RGB', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
draw = ImageDraw.Draw(dst)
draw.ellipse(((  30,30,290,290)),fill=(0, 127, 127), outline=None)
draw.ellipse(((350,30,610,290)),fill=(0, 127, 127), outline=None)

r = 8
for x in range(0,320,12):
    for y in range(0,320,12):
        draw.ellipse((x,y,x+r,y+r),fill=c_v, outline=None)
for x in range(320,640,12):
    for y in range(0,320,12):
        draw.ellipse((x,y,x+r,y+r),fill=c_y, outline=None)
plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.tick_params(bottom=False,left=False,right=False,top=False)
plt.imshow(np.array(dst))
plt.show()


実行していただくと
こんな感じの画像が出力されます。

ball

右と左の大きな円は
実は同じ色なんです!!!!!!

一同「えーーー、なんだってーー」

円が
同じ色に
みえん!!

なんちってね

背景の黄色と紫
その上に乗せた緑色の円

その上に小さな円を載せると
元の円の色が明るく見えたり
暗く見えたりするので

二つの円が違って見えるんだそうな

ソースの

r = 8

を小さくしてもらうと
上に重ねた円の大きさが変わり、
大きな円の色が同じであるということが
わかっていくと思います。

試しにやってみてください

それでは。



 


どーっもーー
AKBの錯視原りのでーーっす

ということで
今回は
「錯視」をやっていきたいと思います。



動画はこちら




さて 
錯視は色々な種類があり
今回紹介するのは
同じ長さや大きさのものだけど
歪んで見える感じの画像を作成していきます。

まずは必要なライブラリの読み込みです。
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt
import numpy as np

%matplotlib inline



それでは有名どころの錯視はらいってみましょうーー

ミュラー・リヤー錯視

同じ大きさの線に少し手を加えると
長く見えたり短く見えたりするやつです。
plt.figure(figsize=(20,9))
size = (800, 400)
color1,color2,width = (150, 100, 220), (200, 120, 200),5

im = Image.new("RGB", size, color=(255, 255, 255))
draw = ImageDraw.Draw(im)

x1,x2,y1,y2 = size[0]//3,size[0]//3*2,size[1]//3,size[1]//3*2

draw.line([(x1,y1),(x2,y1)] , width = width, fill = color2)
draw.line([(x1,y1),(x1-x1//3,y1-y1//3)] , width = width, fill = color1)
draw.line([(x1,y1),(x1-x1//3,y1+y1//3)] , width = width, fill = color1)
draw.line([(x2,y1),(x2+x1//3,y1-y1//3)] , width = width, fill = color1)
draw.line([(x2,y1),(x2+x1//3,y1+y1//3)] , width = width, fill = color1)
draw.line([(x1,y2),(x2,y2)] , width = width, fill = color2)
draw.line([(x1,y2),(x1+x1//3,y2-y1//3)] , width = width, fill = color1)
draw.line([(x1,y2),(x1+x1//3,y2+y1//3)] , width = width, fill = color1)
draw.line([(x2,y2),(x2-x1//3,y2-y1//3)] , width = width, fill = color1)
draw.line([(x2,y2),(x2-x1//3,y2+y1//3)] , width = width, fill = color1)

plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.tick_params(bottom=False,left=False,right=False,top=False)
plt.imshow(np.array(im))
plt.show()

1

こんな感じで、上下の真ん中の棒の長さは一緒です。
ただ上の棒の方がやや少しだけ長く見えます。


カフェウォール錯視

横に引いた線の近くに
交互に四角を配置すると
横の線が斜めになっているように
見えるというものです。

def draw_image(im):
    draw = ImageDraw.Draw(im)
    width = im.size[0]
    box_size = width//5
    half,margin = box_size//2,0
    for j in range(5):
        margin = half//2 if j%2==0 else 0
        for i in np.array(range(5)) * box_size :
            draw.rectangle(((i+margin,j*half),(i+half+margin ,j*half+half)) , outline = None, fill = (0,0,0))
            #pass
    for j in range(1,5):
        
        draw.line([(0,j*half),(size[0],j*half+1)] , width = 3, fill = (160,160,160))
    return im

plt.figure(figsize=(20,9))
size = (800,400)
im = Image.new("RGB", size , color=(255,255,255))

im = draw_image(im)
plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.tick_params(bottom=False,left=False,right=False,top=False)
plt.imshow(np.array(im))
plt.show()


2

横線は斜めに傾いて見えますかね?


エビング錯視

同じ大きさの円を用意して
その周囲に大きい円と小さい円を配置します。

大きい円の中の円が小さく見えて
小さい円の中の円が大きく見えるという錯視です

plt.figure(figsize=(20,9))
size = (640, 320)
im = Image.new("RGB", size, color=(255, 255, 255))

draw = ImageDraw.Draw(im)
c1,c2 = np.array([200, 160]),np.array([500, 160])
r1,r2,r3 = 30,50,15
draw.ellipse(((tuple(c1 - r1)), (tuple(c1 + r1))),fill=(228, 127, 66), outline=None)
draw.ellipse(((tuple(c2 - r1)), (tuple(c2 + r1))),fill=(228, 127, 66), outline=None)
for i in np.radians(range(0,360,60)):
    x2,y2 = np.cos(i)* 120,np.sin(i)* 120
    draw.ellipse((tuple(np.array([x2, y2]) + c1 - r2), 
                  tuple(np.array([x2, y2]) + c1 + r2)),fill=(146, 164, 184), outline=None)
for i in np.radians(range(0,360,45)):
    x2,y2 = np.cos(i)* 60,np.sin(i)* 60
    draw.ellipse((tuple(np.array([x2, y2]) + c2 - r3), 
                  tuple(np.array([x2, y2]) + c2 + r3)),fill=(146, 164, 184), outline=None)
plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.tick_params(bottom=False,left=False,right=False,top=False)
plt.imshow(np.array(im))
plt.show()
3

右のオレンジ円の方が
左のオレンジ円よりも
大きく見えませんか?


ヘリング錯視


中央から放射状に線を描き
それをまたがるように横線を描くと
横線が中央から出る線をまたぐ部分が
膨らんで見えるという錯視です。

plt.figure(figsize=(20,9))
size = (800, 400)
im = Image.new("RGB", size, color=(255, 255, 255))

draw = ImageDraw.Draw(im)
num = 24
times = size[0]//num
color = (150, 100, 220)
for i in range(num):
    draw.line([(i*times,0),(size[0]-i*times,size[1])] , width = 2, fill = (100,100,100))
draw.line([(0,size[1]//3 ),(size[0],size[1]//3 )] , width = 5, fill = color)
draw.line([(0,size[1]//3*2),(size[0],size[1]//3*2)] , width = 5, fill = color)

plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.tick_params(bottom=False,left=False,right=False,top=False)
plt.imshow(np.array(im))
plt.show()
4

中央の横線部分が
膨らんで見えませんかね?



デルブーフ錯視
円の過小視、過大視


青い円の大きさは同じですが
その中や外に円を描くと
元の円の大きさが小さく見えたり
大きく見えたりします。

plt.figure(figsize=(20,9),dpi=300)
size = (640, 320)
im = Image.new("RGB", size, color=(255, 255, 255))

draw = ImageDraw.Draw(im)
color = (0, 200, 220)
draw.arc((150 , 100 , 250 , 200), start=0, end=360, fill=color)
draw.arc((160 , 110 , 240 , 190), start=0, end=360, fill=(0, 0, 0))
draw.arc((350 , 100 , 450 , 200), start=0, end=360, fill=color)
draw.arc((340 , 90   , 460 , 210), start=0, end=360, fill=(0, 0, 0))

plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.tick_params(bottom=False,left=False,right=False,top=False)
plt.imshow(np.array(im))
plt.show()

5

青い円の大きさは一緒ですが
違和感を覚えませんか?


このような錯視は
まだまだ他にもたくさんあります。

今回は一旦PILライブラリで画像を作成して
それをmatplotlibで描画するという方法をとりました。

こうすると簡単に線を引いたりして
錯視画像を作成できます。

みなさまも錯視ができると
とっても錯xyじゃないですかー!!!

って言いたいだけのネタでした。

BIツールの最高峰
Tableauがver10.2になって
Pythonが使えるようになりました

使い方

1.
Tableau10.2をインストールするかアップグレード 

2.
TabPyをダウンロード

git clone git://github.com/tableau/TabPy

gitコマンドでのダウンロードになるので
gitが無い人は要git install 

3.
TabPyディレクトリに移動

cd TabPy

4. 
TabPyサーバーのインストール

sh setup.sh (Macの場合)
setup.bat (Windowsの場合)

※ここでエラーが出るかも知れませんが
普通に使えました

5.
TabPyサーバーを起動

anacondaを既にインストールしている場合
anacondaディレクトリ配下に
インストールされるみたいなので
そこの中のstartup.sh(windowsはstartup.bat)を使って起動させる

起動させるとポート9004で立ち上がる

6.
Tableau側の連携設定

外部サービス接続設定で
no title

サーバー:localhost
ポート:9004
を指定する

※外部サーバーを指定することも可能

これで環境は整ったのであとは使う側


TableauからPythonの呼び出し方

計算式を作り
SCRIPT_REAL関数等を使って呼び出す

構文
SCRIPT_REAL(
'Pythonスクリプト' , 引数指定するメジャー1 , 引数指定するメジャー2 ・・・)

引数は2個以上設定可能なため , で繋げて行く

Pythonスクリプトの部分は
Pythonの関数を定義するような形にする

引数をPython側に渡すには引数名を
_arg1 , _arg2 ・・・のような命名にする

例:
サンプルストアのデータを使って
numpyで売上、利益の相関係数を返す

1

SCRIPT_REAL( '
import numpy as np
return np.corrcoef(_arg1,_arg2)[0,1]
' , 
SUM([売上]) ,
SUM([利益]) )

2つの引数がPython側に渡り
計算値がreturnでTableau側に返ってきます

この場合単に計算式を作って配置しただけだと
式のエラー表示が出ます

これは表計算で
ディメンジョンを使用しているからです

なので式の表計算設定で
使っているディメンジョンを指定してやります
(この場合は顧客名)
フィルターに設定する場合も同様です

最後に
トヨタの株価の推移と
米ドルの価格をつかって
どれだけ相関しているかを求めてみました

toyota

期間でフィルターしており
2016年10月から現在までのトヨタの株価と
米ドルの相関性は93%ほどになりました

期間によっては相関していない部分もあったり
こういう調査をするのにプログラムコードを書かずに
マウス操作だけで出来るようになるのは
Tableauの強みかと思います

因みに
Python連携できるのは
Tableau Desktopか
Tableau Serverだけで
Public版ではできないようです

買うしか無いとかwww



 

前回はシートの作り方をやったので
今回はダッシュボードの作り方です

シートを2つ作りましょう

こんな感じのシートを作りました

40

47
これをダッシュボードにしたいと思います

23
「新しいダッシュボード」をクリックして
ダッシュボードを開きます
25

ここにはダッシュボードに使えるシートが表示されています

ここでシート名を右側にドラッグしてみます
「カード」「コスト」2つをドラッグすると
39

34

こんな感じに2つのシートが表示されます
 
後は調整を

全部を表示させるのは見づらいので
フィルターを追加します

シートでフィルターを設定しておくと
ダッシュボードでもそのフィルターが使用できます

57
「ディメンジョン」から項目を
ドラッグしてフィルターを追加しておきましょう

次はダッシュボード側で設定を
58

追加したシートの右上部分にメニューがあり
そこから「フィルター」で使用したい
項目を選択します

26
こんな感じでフィルターが表示されてきます

ただこれだけだと、片方のシートにしかフィルターが
適用されないため、フィルター右上のメニューから
「ワークシートに適用」「選択したワークシート」
を選択します

37


そして
もう一方のシート名のチェックを入れ
OKを押します
14

これで両方のシートにフィルターがかかります


またシート自体をフィルターにすることも可能です
54
追加したシートの右上にある
「フィルターとして使用」のチェックを入れます

25
 
 こうすることにより
シートの値をクリックした際に
フィルタリングされるようになります

最終的に出来上がりがこんな感じです
シートをフィルター化したものは
再度クリックすると元に戻ります


 

さて
Tableauのインストールをして
どう使っていいかわからない方へ

まずは
使い方を説明します 
Tableauを起動すると
こんな画面のはず
50


まずは可視化したいデータを選択します
エクセルファイルを開きたいなら「Excel」をクリック
 
CSV,TSVファイルなら「テキストファイル」を選択します
ちなみにpublic版ではデータベースに接続できません
簡単なデータにしか使えないのです

データベースのデータを使いたい場合は
一旦csvなどに加工しておくのが良いでしょうね


次にファイルを開いてみます
こんな感じのエクセルデータを用いるとします
カード名 パック レア度 クラス カード種別 Cost ATK HP 評点
ウォーターフェアリー プライズ ブロンズ エルフ 1 1 1 1 7
ベビーエルフ・メイ STD ブロンズ エルフ 1 1 1 1 9.5
ブレイブフェアリー STD ブロンズ エルフ 1 1 1 1 4
フェアリー STD ブロンズ エルフ 1 1 1 1 0
ベビーフェルパー ROB ブロンズ エルフ 1 1 1 1 0
自然の導き STD ブロンズ エルフ 3 1 0 0 8
フェアリーサークル STD ブロンズ エルフ 3 1 0 0 8
絡みつく蔦 ROB ブロンズ エルフ 3 1 0 0 0
森の聖域 STD シルバー エルフ 2 1 0 0 4

これを開くと・・・

44

こんな画面になるはずです
ここでは接続するデータソースの設定を行います

エクセルを開くと左側のシート欄に
シートの名前が出てきます

ここでシート名を
「ここにシートをドラッグ」の部分に
ドラッグします

07


データ表示されたんじゃないかと思います

因みに取り扱うデータには注意が必要です
それは
・1行目がヘッダー行の表形式
・データが埋まっていること
・表が結合されていないこと

これに当てはまっていない場合
少しエクセルの加工が必要だったり
Tableau側での整形が必要だったりするので
気をつけましょう

次に
Tableau側で「シート」をクリックします
画面下に表示されている「シート1」
をクリックします
これでシートに移動できます
03

Tableauでは
・1つの表計算を扱うシート
・シートをまとめたダッシュボード
・シートとダッシュボードをまとめられるストーリー
この3つの形式を構築することができます

シートをいくつか作成し
それをダッシュボードにまとめて表示させるのが
主な使い方となるでしょう

Tableauでは
データが
「ディメンジョン」
「メジャー」
の2つで構成されています

どの粒度で計算させる、というのがディメンジョン
計算値がメジャーになります

ディメンジョンは
質的データにあたり
名前、種別、年月日などが当てはまります

メジャーは
量的データにあたり
枚数、売上、利益、利益率など
数値で現されるものや
レコード数などのデータになります

エクセルファイルを取り込んだ時点で
データは自動で振り分けられますが
例えば種別を1,2,3などとしていた場合
これはメジャーに振り分けられてしまうので

メジャーからディメンジョンに移す必要があります

45

種別を右クリックして
「ディメンジョンに変換」を選択し
移動させます

では早速
ディメンジョンから
「クラス」を「列」へ
「レア度」を「」へドラッグします

そうするとこんな感じになるので
30

次に集計させたいメジャーとして
「レコード数」を2回、「マーク」の
「ラベル」「色」の所に
ドラッグします

すると
37

こんな感じでクロス集計されます
クラス別、レア度別での
カード枚数が集計され表示されます

03

またディメンジョンを追加します
「パック」を行に追加すると
集計粒度にパックの要素が追加されます


ここで表示を変えてみましょう
右側にある表示形式で
積み上げ棒グラフを選んでクリックします

43
そうすると

42

こんな感じに棒グラフ表示に切り替わりました
他にもいろんな表示ができますが
棒グラフ表示を用いることが殆どです

これだと少し見づらそうなので
縦横の配置と粒度の順番を変えます

21
画面上部に行と列の交換があるので
これをクリックすると行列が入れ替わります

あとは画面上の「レア度」の部分をドラッグで
順番をレアの順に入れ替えて

19

表示のサイズを「ビュー全体」を
指定します

あとは多い順に並べ替えたいので
行の「クラス」を右クリックして
並び替えを選択
31

「フィールド」レコード数で降順にしてOKを押します

すると
40

こんな感じに
だいたい一目で把握できる形になりました

色合いを変えたいときは
「色」か「書式設定」で変更します

以上がざっくりとした使い方です

割と感覚的に使える感じなので
とりあえずデータをドラッグして
どう変化するのかを試してみるのがいいでしょうね
 

このページのトップヘ