好久好久之前,咱們在 python 裏面畫圖都是用 matplotlib 這個包,固然如今好像也還在用它,不過我一直以來都不太喜歡這種方式,由於 matplotlib 畫出來的圖都是靜態圖片,雖然作簡單的展現沒什麼壓力,可是圖形複雜後就不方面了,好比說下面這些場景:css
因此差很少兩年前左右,爲了既能在 ipython notebook 裏作數據分析和研究,又能有個地方來作數據展現,我搞了個開源項目:Ipython Notebookhtml
下面是一張在 github 上的項目介紹截圖:前端
下面是在 youtube 上的 demo 視頻,不要問我爲何不放 youku 的連接,由於不想在優酷的廣告時間插播,哈哈。python
當時這個項目作了幾個月,小有成效,徹底夠用,可是在 2016.04 後就沒有再更新過了,由於當時這個項目是爲了作數據展現用的,要展現的數據是本身作量化策略的一些分析結果,而後當時由於這個項目差很少已經夠用了,就沒有再繼續作下去,而是把更多的時間花在量化策略研究上面了。git
而後在2016.04 到最近的一年多裏,我發現有不少人 star 和 fork 了我這個項目,差很少從 200不到的 star 增長到近 300 個star了,說實話雖然不是不少,可是我內心仍是很感謝各位捧場的朋友的。只是我我的的行事風格向來都是 只關注最核心的事,因此之後也不會再花時間在這個項目上了,而且如今我已經有了更方便快捷好用的,直接能在 ipython notebook 裏畫動態交互圖的方案,因此其實我本身也已經棄用了這個項目了。github
不過看到還有這麼多人在關注這個項目,我想你們也許跟之前的我同樣,很想要一種在 ipython notebook 裏畫動態交互圖的工具和方法。因此我準備把如今本身是如何解決這個問題的方案寫出來跟各位一塊兒分享,算是感謝各位一直對這個項目的關注了。sql
IPython.core.display.publish_display_data
這樣一個內置函數,可讓用戶指定輸出到 notebook 中要展現的數據是什麼樣的。IPython.core.display.publish_display_data
函數把圖表數據插入到 notebook 裏面。下面,咱們就從要作的工做出發,分兩步來完成這個工做。後端
如今最經常使用的動態交互圖的前端框架大概有下面幾個:highcharts,d3.js,nvd3.js,echarts,c3js 這幾個,首先明確一點,要想經過 python 來搞一個 html 格式的交互圖,確定須要間接的經過上面這些 js 庫來實現。你別跟我說你要用 python 來從 0 到 1 生成一個 html 格式的圖,要否則我真的會對你五體投地~。既然如此,那就先看看 google 大法,分別搜搜 python highcharts
,python d3.js
啥的,看看有沒有前人已經把輪子造好了。bash
果不其然,網上已經有很多輪子了,那接下來的工做就是衆水三千,看你用哪一個瓢了,哦,不對,是看你喝哪一瓢了~前端框架
最後我選的是 highcharts 的一個實現,github.com/arnoutaertg…,緣由有幾點:
ok,其實找到這個庫以後,基本上就完成大半工做了,只須要把這個庫針對數據分析,展現的場景再優化優化就能夠了,因此接下來,我算是站在巨人的肩上,作了兩件小事:
IPython.core.display.publish_display_data
函數下面分開來講:
都是簡單的活兒,直接看核心代碼咯,別跟我說看不懂代碼,曾經一個同事要求跟我開發一個 module,結果尼瑪他一個星期都看不懂千來行的代碼,還讓我給他畫架構圖,WTF~~~
def draw(df, x, y, title=None, **kwargs):
"""核心畫圖代碼,傳入 dataframe,和相關的配置,返回圖表對象,在 notebook 場景下可直接展現 該函數包裝了 charts 包的一個接口,使之更方便的適配 pandas dataframe 數據結構 參數: df:dataframe 數據結構 x(int / str): x 座標軸,必須是傳入的 df 的某一個 column y(list): y 座標軸,必須在傳入的 df 的column中出現 title:圖表名字 kwargs:可選參數,默認都是 charts 支持的參數,如: x_type: x 座標軸的數據類型,默認是 datetime 類型 x_labels: 可自定義 x 座標軸的 label 內容 subtitle: 子標題內容,能夠顯示一些圖標的統計指標 width: 圖表寬度 height: 圖表高度 options: 圖表 options,不經常使用,能夠直接參考源碼中的默認配置 返回: charts 的圖表對象,在 notebook 中能夠直接運行展現 """
my_options = copy.deepcopy(options)
title = title if title else str(y)
my_options['title']['text'] = title
tmp = df[[x] + y]
x_type = kwargs.pop('x_type') if 'x_type' in kwargs else 'datetime'
x_labels = kwargs.pop('x_labels') if 'x_labels' in kwargs else None
subtitle = kwargs.pop('subtitle') if 'subtitle' in kwargs else ''
if x_type == 'datetime':
tmp.set_index(x, inplace=True)
tmp.index = tmp.index.to_datetime()
else:
my_options['xAxis']['type'] = x_type
my_options['xAxis']['categories'] = df[x].tolist()
if x_labels:
my_options['xAxis']['categories'] = x_labels
if 'options' in kwargs:
my_options.update(kwargs.get('options'))
kwargs.pop('options')
if 'width' in kwargs:
my_options['width'] = kwargs.get('width')
if 'height' in kwargs:
my_options['height'] = kwargs.get('height')
if subtitle:
my_options['subtitle']['text'] = subtitle
return charts.plot(tmp, options=my_options, show='inline', display=y, **kwargs)
複製代碼
ok, 到此,從 dataframe 到動態圖表已經搞定了,接下來是如何結合到 ipython notebook 中,其實,上面幾乎已經完成大半了,由於若是這個畫圖函數是在 notebook 中的單元格里最後運行的一個函數,且沒有把返回結果顯示的賦予一個變量的話,notebook 會默認展現函數輸出的結果的。好比下面截圖:
上面截圖裏,咱們把圖表對象放到一個變量 figure 裏了,這個 figure 變量有個屬性:figure.data
,裏面存儲的就是字符串格式的 html 格式的圖表源碼,so 那就簡單多了,直接複用函數就搞定了: lambda figure: IPython.core.display.publish_display_data({'text/html': figure.data})
def print_html(html_text):
"""將 charts 圖表的 html 數據手動展示,通常適用於循環做圖的場景 """
IPython.core.display.publish_display_data({'text/html': html_text})
複製代碼
下面簡單展現下效果,爲了你們方便,我把測試數據也準備好了,因此這個 notebook 你們是能夠直接下載下來運行的,個人環境是:python 2.7 + ipython 3.2.2
按照節奏,如今通常應該把源碼和案例全放上來了,ok:
回頭再看看有木有必要提個 pr 到那哥們的 repo 裏。
最後貼上我幾乎每天在用的一個案例,真正實現了一鍵出圖,哈哈:litaotao.github.io/files/repor…
首先仍是感謝各位 star 了個人項目的朋友們,下面大家能夠來 star 個人博客吧,源碼和demo我都放到博客下的 files 下面了。哈哈。雖然不會常常更新【常常更新就必定是好事?】,可是保證在一些場景下,絕對比之前的好用好多好多倍呢,因此快來 star 吧。
而後是想聊聊作這個項目的一些感觸,如今回想,一開始作的時候超興奮的,甚至有時候回家了還調試,特別是一邊現學 html/css/js 那些東西,一邊先後端結合起來調試,偶爾還有種 欲與天公試比高 的激動。不過當時作到後來,我竟然開始添加一些很雞肋的功能【好比說 sql】,當時想的是添加一個 online sql query & visualization,幸虧 2016年初來了個股災3.0,讓虧了10幾個點的我及時止步,我記得當時再決定是否要繼續作這個 sql 工具的時候,我當時的心裏獨白大概是下面這樣子的:
一個能夠動態畫圖的工具。
固然是投資策略了,你妹的,我搞工具幹嗎~
由於蛋疼,想在 github 上多攢點 star,哈哈。
你妹的,這還用問嗎?
好吧,我浪子回頭,工具夠用就好了,我要專心研究策略了。
如今,我仍是很慶幸當時沒有繼續搞這個項目,而是把這些時間放到研究上去了,這一年多了在研究方面積累了我我的看來至關有養分的東西。
其實結合起一些經驗來看,我發現大千世界真的事事向通。好比說,最近兩三年關於創業不少的幾本書:《創業維艱》,《精益創業》,《The One Thing》,我總結下來,其實能夠簡單的說:找到一個核心問題,而且找到一個能解決這個核心問題的解決方案,而後不斷的把這個方案作到極致。是否是很熟悉,立刻我就能在之前看過的雞湯書裏找到幾句雷同的話,好比說我大新東方總教頭餘老師說的 「努力作到行業內的 top 20」;好比說如今的我大中華傳承了幾千年的經驗 「360行,行行出狀元」。若是這些都比較虛,那能夠簡單反思本身,在你買的不少東西中,無論網上網下,真實的仍是虛擬的,你是由於它功能豐富買單呢?仍是由於它真切的解決了你的某一項需求而付錢呢?相似的論斷,我也在前段時間寫的工做感悟中有提到,在這裏,第八條: 工做 3 年後的一些思考【Part 3】
好像又扯了很多了,最後感謝下開發了這個 github.com/arnoutaertg… repo 的哥們,的確省了我很多時間,而後也感謝各位觀衆們,哈哈,不要忘了給我 star 啊,哈哈哈哈~~~