plotly繪圖說明

(可以不看的廢話)

從上篇博客開始就一直在忙患朱,忙了好幾個(gè)月的文章以后鲁僚,最近終于是在一個(gè)deadline之前把文章投了出去,所以也就可以重新回歸寫博客的日子了裁厅。在新年之前蕴茴,再看看能不能寫一兩篇的博客吧。當(dāng)然看的人可能也不是很多就是姐直。
關(guān)于今天的這篇博客倦淀,主要還是來講一下我現(xiàn)在超級(jí)超級(jí)超級(jí)喜愛和用的也很得心應(yīng)手的python的一個(gè)畫圖的包--plotly。

更新預(yù)告(flag): 可能會(huì)寫一些關(guān)于speciation的東西声畏。

plotly介紹

plotly是一個(gè)開源的python的庫撞叽,本質(zhì)上它應(yīng)該是一個(gè)收費(fèi)的企業(yè)級(jí)的軟件,官網(wǎng)在plotly插龄,它對(duì)自己公司的定位即

Modern Analytics Apps for the Enterprise

所以其實(shí)是它們的公司想必除了開發(fā)plotly以外還是想做一些分析的平臺(tái)的工作的愿棋,應(yīng)該是偏向于統(tǒng)計(jì)分析的部分,當(dāng)然這不是我們需要關(guān)注的地方均牢】酚辏回到plotly本身,plotly其實(shí)主要是一個(gè)基于d3.js開發(fā)的一個(gè)js的庫徘跪,而除了js的開發(fā)以外甘邀,它也對(duì)不同的編程語言開發(fā)了多種多樣的庫和工具包。例如R垮庐、matlab松邪、python。由于它的核心代碼其實(shí)js哨查,其它的工具包和庫其實(shí)僅僅是作為一個(gè)相應(yīng)的編程軟件對(duì)js的一個(gè)API逗抑,所以我們就不詳細(xì)的討論它的源代碼了 (畢竟我也看不太懂。。邮府。)荧关,而在plotly.py中,相關(guān)的內(nèi)容也藏的比較深褂傀,結(jié)構(gòu)比較復(fù)雜忍啤,我也不想過于深入的去討論它的源碼。

除了對(duì)plotly的背景介紹外紊服,plotly能做的事情當(dāng)然是重中之重的介紹點(diǎn)檀轨⌒鼐海基于js的繪圖庫最大的特點(diǎn)就是可交互欺嗤。最原始的output結(jié)果是html格式的,所以輸出的結(jié)果就是一個(gè)使用plotly.js進(jìn)行繪制的一個(gè)網(wǎng)頁卫枝,當(dāng)然如果是需要它生成一個(gè)靜態(tài)的圖的話也是沒什么問題的煎饼,它同樣也支持直接生成pdf,png之類的校赤。

plotly的資料

plotly這個(gè)軟件在國(guó)內(nèi)的使用率似乎并不高吆玖,所以很多中文的相關(guān)資料都十分的匱乏,所以資料方面也不是很多马篮,這里就只放一個(gè)plotly的官網(wǎng)以及一個(gè)Stack Overflow的專區(qū)的鏈接好了沾乘。

官網(wǎng)鏈接
stack overflow tagged plotly

plotly的起始(哲學(xué))

由于我使用plotly也有一段時(shí)間了,加上如果我從基礎(chǔ)開始講一個(gè)庫的使用其實(shí)也十分的沒有意思浑测,還不如讓你們直接去看官網(wǎng)的教程(畢竟我自己就是這么開始的)翅阵,所以我在這里從著重講一些高度概括的,一些更為核心的東西迁央。不要求初學(xué)者一看就能懂掷匠,但是可以在聽說了這些哲學(xué)以后,在學(xué)習(xí)和掌握plotly中更為得心應(yīng)手岖圈,我也覺得這才是一個(gè)博客的意義所在讹语,而不是照搬照抄,那完全只是一堆冗余知識(shí)的堆疊蜂科。

  1. 層/蹤跡(trace)的思想

plotly的設(shè)計(jì)上相較于matplotlib這些庫顽决,思想上更為接近photoshopillustrator。所以對(duì)于接觸過這些的人來說也更為便于學(xué)習(xí)和理解导匣。意思就是說擎值,在畫一張圖時(shí),基本單位應(yīng)該是一層逐抑,這一層原則上應(yīng)該是同類的對(duì)象(例如scatter, bar, box, heatmap等)鸠儿,初學(xué)者都可以把這些認(rèn)為是一些對(duì)象(高級(jí)玩家可以自定義對(duì)象,因?yàn)橄駂eatmap就是一堆bar的堆疊嘛。)

  1. data與layout分離

除了上一個(gè)中說的層的思想进每,層都是在data內(nèi)部的汹粤。然后就是說layout和data都是分離的,這個(gè)其實(shí)很好理解田晚,因?yàn)橄駇atplotlib之類的繪圖庫其實(shí)也差不多嘱兼,所以這個(gè)也不多加講解。

  1. 基于dict (json)的數(shù)據(jù)結(jié)構(gòu)

在上述的plotly的介紹中其實(shí)講到了一個(gè)很重要的一點(diǎn)贤徒,也就是plotly的核心是一個(gè)js的庫芹壕,那么與庫交流時(shí),最常見的是一種叫json的數(shù)據(jù)結(jié)構(gòu)接奈,json的數(shù)據(jù)結(jié)構(gòu)在python中不是一種常規(guī)的數(shù)據(jù)結(jié)構(gòu)踢涌,但是最為相近的也就是dict,所以plotly.py在設(shè)計(jì)時(shí)序宦,也就將一張圖的數(shù)據(jù)睁壁,定位在dict上。
那么plotly的這種思想有什么特點(diǎn)呢互捌?在后面具體的例子中大家應(yīng)該會(huì)有更深的體會(huì)潘明,這里只簡(jiǎn)單的說。dict類似的數(shù)據(jù)結(jié)構(gòu)秕噪,非常方便大家記憶和查找相關(guān)的屬性钳降。像最為基礎(chǔ)的python的一個(gè)繪圖庫matplotlib,我用不慣的原因很大程度上就是因?yàn)樗幕ハ嘁煤蛿?shù)據(jù)結(jié)構(gòu)過于復(fù)雜彎曲腌巾,一個(gè)figure有axes遂填,axes又可以繞回figure,所以不是一個(gè)單向的純粹的層級(jí)結(jié)構(gòu)壤躲。plotly的設(shè)計(jì)則十分的簡(jiǎn)潔明了城菊。

  1. 子圖(subfigure)和坐標(biāo)軸(axes)及其標(biāo)簽(ticklabels)是相互獨(dú)立的

在繪圖時(shí),除開了以上幾點(diǎn)碉克,最需要細(xì)心的地方也是最容易出問題的地方就是子圖或者坐標(biāo)軸這些問題了凌唬。其中坐標(biāo)軸的標(biāo)簽也是勸退大部分人的地方,plotly的設(shè)計(jì)我也不確定是好是壞漏麦,但是它將每一個(gè)子圖和坐標(biāo)軸割裂開了客税,通過layout中的一些名稱進(jìn)行綁定,你可以使坐標(biāo)軸綁定多個(gè)子圖撕贞,也可以讓子圖自由的伸展更耻、排布成不同的布局。同時(shí)捏膨,標(biāo)簽這些也是很容易的去設(shè)置秧均,只要你了解不論是類別變量的標(biāo)簽(ticktext)還是數(shù)值變量的標(biāo)簽(ticktext)其實(shí)本質(zhì)都是基于數(shù)值變量的標(biāo)簽(tickvalues)食侮,前兩個(gè)是看到的,最后一個(gè)大部分時(shí)候是隱藏的目胡。

  1. 交互動(dòng)畫的開關(guān)機(jī)制

上面講的一些其實(shí)都是跟交互沒太大關(guān)系的锯七,最終當(dāng)然也能實(shí)現(xiàn)交互的結(jié)果,不過那些更多的是由于本身就自帶的縮放(scale/zoom)的功能了誉己。plotly中眉尸,所有的交互,例如button巨双、slider和play都是在layout中的噪猾,這一點(diǎn)一定程度上是為了適應(yīng)js的代碼吧。因?yàn)閜lotly的基本邏輯是這樣的筑累,你把所有你需要繪制的東西全部一次性的放在一個(gè)figure內(nèi)部袱蜡,然后通過layout中的updatemeanus內(nèi)的開關(guān)進(jìn)行調(diào)控。而這些開關(guān)其實(shí)都直接對(duì)應(yīng)到了js的一些function疼阔,然后通過這些函數(shù)實(shí)現(xiàn)點(diǎn)擊(click)button/拖動(dòng)slider時(shí)戒劫,隱藏某些traces半夷,顯示某些traces這樣子的功能以達(dá)到交互(interactive)的功能婆廊。

plotly的哲學(xué)基本上以上的幾點(diǎn),在了解和知道這些的基礎(chǔ)上巫橄,我覺得可以更好的去理解和使用這個(gè)繪圖的庫淘邻。

plotly的基本使用(結(jié)合上述提到的所謂plotly哲學(xué)的一些demo)

trace和dict

import plotly
import plotly.graph_objs as go

import numpy as np

N = 1000
random_x = np.random.randn(N)
random_y = np.random.randn(N)

# Create a trace
trace1 = go.Scatter(
    x = random_x,
    y = random_y,
    mode = 'markers'
)
random_y2= np.random.randn(N)

trace2 = go.Bar(x = random_x,y = random_y2)
data = [trace,trace2]

plotly.offline.plot(dict(data=[trace,trace2]))
demo1

最終它可以輸出這樣的一個(gè)圖,其實(shí)理論上說這個(gè)圖(毫無意義)湘换,也很宾舅,但其實(shí)我只是為了說明bar 圖和scatter圖的共存,在plotly中彩倚,他們兩個(gè)屬于兩個(gè)互不干擾的trace筹我,并且,每次初始化一個(gè)trace時(shí)帆离,除了直接使用go.Scatter或者go.Bar以外蔬蕊,內(nèi)容物真的只需要通過類似于dict的方式就可以指定。如上的代碼哥谷。

subplot岸夯、interactive和dict

import plotly
import plotly.graph_objs as go
import plotly.figure_factory as ff
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import *
dataset = fetch_california_housing()
X_full, y_full = dataset.data, dataset.target

X = X_full[:, [0, 5]]

distributions = dict([
    ('Unscaled data', X),
    ('Data after standard scaling',
        StandardScaler().fit_transform(X)),
    ('Data after min-max scaling',
        MinMaxScaler().fit_transform(X)),
    ('Data after max-abs scaling',
        MaxAbsScaler().fit_transform(X)),
    ('Data after robust scaling',
        RobustScaler(quantile_range=(25, 75)).fit_transform(X)),
    ('Data after power transformation (Yeo-Johnson)',
     PowerTransformer(method='yeo-johnson').fit_transform(X)),
    ('Data after power transformation (Box-Cox)',
     PowerTransformer(method='box-cox').fit_transform(X)),
    ('Data after quantile transformation (gaussian pdf)',
        QuantileTransformer(output_distribution='normal')
        .fit_transform(X)),
    ('Data after quantile transformation (uniform pdf)',
        QuantileTransformer(output_distribution='uniform')
        .fit_transform(X)),
    ('Data after sample-wise L2 normalizing',
        Normalizer().fit_transform(X)),
])

y = minmax_scale(y_full)
# scale the output between 0 and 1 for the colorbar

# 
fig = plotly.tools.make_subplots(rows=2,cols=2,specs=[[{},None],[{},{}]],shared_xaxes=True,shared_yaxes=True)
#This is the format of your plot grid:
#[ (1,1) x1,y1 ]      (empty)    
#[ (2,1) x2,y2 ]  [ (2,2) x3,y3 ]
# 初始化了一個(gè)如上的一個(gè)figure布局,以便進(jìn)行繪圖

traces = []
for scaler,scaled_X in list(distributions.items())[:1]:
# 只畫第一個(gè)的話们妥,如下
    _fig1 = ff.create_distplot([scaled_X[:,0]], ['a'],show_hist=False,show_rug=False)
    _fig2 = ff.create_distplot([scaled_X[:,1]],['a'],show_hist=False,show_rug=False)
    trace = go.Scatter(x=scaled_X[:,0],y=scaled_X[:,1],mode='markers',marker=dict(color=y),yaxis='y2',xaxis='x2',name=scaler,legendgroup=scaler)
    fig.append_trace(go.Scatter(x=_fig1.data[0]['x'],y=_fig1.data[0]['y'],mode='lines',name='upper left',legendgroup=scaler),1,1)
    fig.append_trace(go.Scatter(x=_fig2.data[0]['y'],y=_fig2.data[0]['x'],mode='lines',name='down right',legendgroup=scaler),2,2)
    fig.append_trace(trace,2,1)

fig.layout.xaxis1.domain = [0,0.8]
fig.layout.xaxis2.domain = [0,0.8]
fig.layout.xaxis3.domain = [0.85,1.0]
fig.layout.yaxis1.domain = [0.85,1.0]
fig.layout.yaxis2.domain = [0,0.8]
fig.layout.yaxis3.domain = [0,0.8]
fig.layout.width = 1000
fig.layout.height = 1000
plotly.offline.plot(fig)

上面的代碼畫出來是這樣的猜扮。


demo2

由于是交互的,我覺得大家最好還是自己試一試會(huì)體會(huì)更深监婶。(當(dāng)然我要是放在jupyter notebook上也就更好了旅赢,但是我有點(diǎn)懶齿桃。。煮盼。)

那么我們上面的代碼僅僅只畫了一個(gè)源譬,那怎么能行呢!對(duì)吧孕似。接下來我們?cè)?strong>上面的代碼的基礎(chǔ)上踩娘,再加一些東西,使它更有意思起來喉祭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末养渴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子泛烙,更是在濱河造成了極大的恐慌理卑,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔽氨,死亡現(xiàn)場(chǎng)離奇詭異藐唠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鹉究,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門宇立,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人自赔,你說我怎么就攤上這事妈嘹。” “怎么了绍妨?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵润脸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我他去,道長(zhǎng)毙驯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任灾测,我火速辦了婚禮爆价,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘行施。我一直安慰自己允坚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布蛾号。 她就那樣靜靜地躺著稠项,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鲜结。 梳的紋絲不亂的頭發(fā)上展运,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天活逆,我揣著相機(jī)與錄音,去河邊找鬼拗胜。 笑死蔗候,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的埂软。 我是一名探鬼主播锈遥,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼勘畔!你這毒婦竟也來了所灸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤炫七,失蹤者是張志新(化名)和其女友劉穎爬立,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體万哪,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侠驯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奕巍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吟策。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖伍绳,靈堂內(nèi)的尸體忽然破棺而出踊挠,到底是詐尸還是另有隱情乍桂,我是刑警寧澤冲杀,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站睹酌,受9級(jí)特大地震影響权谁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜憋沿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一旺芽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辐啄,春花似錦采章、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至砸民,卻和暖如春抵怎,著一層夾襖步出監(jiān)牢的瞬間奋救,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工反惕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尝艘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓姿染,卻偏偏與公主長(zhǎng)得像背亥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子悬赏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,097評(píng)論 1 32
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫隘梨、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評(píng)論 4 62
  • 這是我在校園網(wǎng)上看到曾經(jīng)一位學(xué)姐留詩舷嗡,感覺很美轴猎。但是后來又特意咨詢了學(xué)中文的,說进萄,對(duì)仗不工整blabla... 但...
    司徒小歪閱讀 526評(píng)論 0 1