Django上使用數據可視化利器Bokeh解析
前言
最近在實驗室做的一個項目中,需要把大量的數據在 web 端進行可視化,需要繪制各類圖表。數據都是以 csv 文件的形式保存在服務器中。本來是想使用 D3.js 這個數據可視化前端庫來畫圖,但是需要編寫大量的 js 代碼。后來發(fā)現了 Bokeh 這個框架,只需要在后端編寫及少量的 Python 代碼生成對應的 html 與 js,再傳送到前端讓瀏覽器解析,大大的減少了工作量。
1. 波形圖
這里繪制一個包含了數千個數據點的信號波形圖,繪制方法和 Matlab 如出一轍。學習成本為零。
import pandas as pd from bokeh.plotting import figure from bokeh.io import output_file, show csv_file = 'points.csv' data = pd.read_csv(csv_file) TOOLS = 'hover,crosshair,pan,wheel_zoom,box_zoom,reset,save,box_select' picture = figure(width=1000, height=400, tools=TOOLS) picture.line(data['order'], data['value'], color='blue', alpha=0.5) output_file('waveform.html', title='waveform') show(picture)
points.csv 中包含了 2048 個點。上面這段腳本是直接生成了一個 html 文件,show(picture)語句打開了這個 html 文件。效果如下:
右側的工具欄是通過TOOLS = 'hover,crosshair,pan,wheel_zoom,box_zoom,reset,save,box_select'設置的。包含了常見的一些功能,包括縮放,保存,重置等等。由于簡書的 markdown 不支持直接插入 div 塊和 js 腳本,所以只能截取一個圖放在這里,不能體驗到右側的工具欄的使用感受。
2. 集成到 Django 中
上面的例子是直接生成了一個 html 文件,但在正常的使用中,只應該生成對應的 div 和 js 就行了。
在 Django 的 view.py 中,定義一個 view。
def waveform(request): csv_file = 'your file' data = pd.read_csv(csv_file) TOOLS = "hover,crosshair,pan,wheel_zoom,box_zoom,reset,save,box_select" picture = figure(width=1200, height=400, tools=TOOLS) picture.line(data['order'], data['value'], color='blue', alpha=0.5) script, div = components(picture, CDN) return render(request, 'waveform.html', {'script': script, 'div': div})
這樣就把對應的 template 的 waveform.html 中:
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Experiment with Bokeh</title> <link href="{% static 'bokeh-0.12.4.min.css' %}" rel="stylesheet" type="text/css"> <link href="{% static 'bokeh-widgets-0.12.4.min.css' %}" rel="stylesheet" type="text/css"> <script src="{% static 'bokeh-0.12.4.min.js' %}"></script> <script src="{% static 'bokeh-widgets-0.12.4.min.js' %}"></script> {{ script |safe }} </head> <body> {{ div |safe }} </body> </html>
這里有一個不太好的地方,把 script 放到了 head 里面。
然而要是放在底部。就不能正確畫出圖了。(求大神解答)
3. 時頻圖
在經過短時傅里葉變換輸出的結果,可以用 image 來顯示時頻分布圖。與 Matlab 畫出來的也是如出一轍。
import numpy as np import pandas as pd from bokeh.io import output_file, show from bokeh.plotting import figure data = pd.read_csv('tf_stft.csv') value = np.array(data['value']) d = np.reshape(value, (338, 124)) d = np.transpose(d) TOOLS = "hover,crosshair,pan,wheel_zoom,box_zoom,reset,save,box_select" p = figure(x_range=(0, 62), y_range=(0, 169), tools=TOOLS) p.image(image=[d], x=0, y=0, dw=62, dh=169, palette="Viridis256") output_file("image.html", title="image.py example") show(p)
結果如下:
如果是使用 D3.js 來繪制這個圖形的話,就比較費勁了。
4. 小結
Bokeh 這個框架,比起 D3.js,它的可視化選項相對較少。因此,目前來看 Bokeh 無法挑戰(zhàn) D3.js 的霸主地位。而且 Bokeh 過于依賴 python 的數值計算庫,并非一個純前端的框架,使得它的使用范圍也小于 D3.js。
而在純 python 的數值計算領域,也已經有 matplotlib 這種提供了與 Matlab 一模一樣的接口的數據可視化庫,Bokeh 的適用場景也并不多。
但是,它非常適合嵌入 Flask 或者 Django 的程序中,非常好用,速度也很快。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
零基礎寫python爬蟲之使用urllib2組件抓取網頁內容
文章詳細介紹了在python2.5環(huán)境下,如何使用urllib2這個python自帶的組件進行抓取指定網頁內容的,整個過程記錄的非常的詳細,也很簡單,有需要的朋友可以參考下,寫出自己的python爬蟲2014-11-11