Bokeh 初探

之前本來想想研究下 pandas+highchart 的解決方案,網(wǎng)上搜了下發(fā)現(xiàn)Bokeh 這個(gè)好東西,簡(jiǎn)單易用,天然就是支持python 和 pandas。而且很多場(chǎng)合都能用 (可以純python用,可以在jupyter里面用,可以和flask結(jié)合用,甚至有自己的bokeh server), 挺有意思的

官方網(wǎng)址: http://bokeh.pydata.org/en/latest/
Github: https://github.com/bokeh/bokeh

安裝

bokeh需要這幾個(gè)庫(kù):

  • NumPy
  • Jinja2
  • Six
  • Requests
  • Tornado >= 4.0
  • PyYaml
  • DateUtil

最方便的方式還是在anacode 下面安裝, 用這個(gè)命令 conda install bokeh

簡(jiǎn)單的例子

from bokeh.plotting import figure, output_file, show

# prepare some data
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]

# output to static HTML file
output_file("lines.html")

# create a new plot with a title and axis labels
p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')

# add a line renderer with legend and line thickness
p.line(x, y, legend="Temp.", line_width=2)

# show the results
show(p)

Jupyter 中的使用

先導(dǎo)入下面的package. from bokeh.io import push_notebook, show, output_notebook, 再用 output_notebook() 設(shè)置輸出在jupyter notebook里面。( 一般情況是用output_file()輸出為html文件。) 這樣還不夠, 還需要在show()函數(shù)設(shè)置 notebook_hanlde 參數(shù)為True。
下面是個(gè)官方的例子:

from bokeh.io import push_notebook, show, output_notebook
from bokeh.layouts import row
from bokeh.plotting import figure
output_notebook()

opts = dict(plot_width=250, plot_height=250, min_border=0)
p1 = figure(**opts)
r1 = p1.circle([1,2,3], [4,5,6], size=20)

p2 = figure(**opts)
r2 = p2.circle([1,2,3], [4,5,6], size=20)

# get a handle to update the shown cell with
t = show(row(p1, p2), notebook_handle=True)

可以用push_notebook() 函數(shù)更新上面的渲染的圖像。在上面的代碼后建新的cell:

# this will update the left plot circle color with an explicit handle
r1.glyph.fill_color = "white"
push_notebook(handle=t)

運(yùn)行完后可以發(fā)現(xiàn)上面cell的輸出圖像變化了。

可以去github中example->howto->notebook_comms->basic Usage.ipynb 自己下載下來玩

chart 庫(kù) + pandas

如何方便的bokeh去快速渲染pandas的數(shù)據(jù)呢, 用chart, chart 庫(kù)的使用說明可以去http://bokeh.pydata.org/en/latest/docs/reference/charts.html

簡(jiǎn)而言之,chart 庫(kù)下面支持下面的幾種渲染類型:

  • Area
  • Bar
  • BoxPlot
  • Chord
  • Donut
  • HeatMap
  • Horizon
  • Line
  • Scatter
  • Step
  • TimeSeries
    一個(gè)例子:
from bokeh.charts import Histogram, output_file, show
from bokeh.layouts import row
from bokeh.sampledata.autompg import autompg as df

hist = Histogram(df, values='mpg', title="Auto MPG Histogram", plot_width=400)
hist2 = Histogram(df, values='mpg', label='cyl', color='cyl', legend='top_right',
                  title="MPG Histogram by Cylinder Count", plot_width=400)

output_file('hist.html')
show(row(hist, hist2))

bokeh的sample data里面自帶一些pandas 的dataframe的數(shù)據(jù)

mpl 庫(kù)

我之前其實(shí)已經(jīng)有用matplotlib.pyplot 庫(kù)去產(chǎn)生圖片了,mpl庫(kù)提供了一個(gè)快速替換的方法。

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from scipy import optimize

from bokeh import mpl
from bokeh.plotting import output_file, show

# Set the palette colors.
sns.set(palette="Set2")

# Build the sin wave
def sine_wave(n_x, obs_err_sd=1.5, tp_err_sd=.3):
    x = np.linspace(0, (n_x - 1) / 2, n_x)
    y = np.sin(x) + np.random.normal(0, obs_err_sd) + np.random.normal(0, tp_err_sd, n_x)
    return y

sines = np.array([sine_wave(31) for _ in range(20)])

# Generate the Seaborn plot with "ci" bars.
ax = sns.tsplot(sines, err_style="ci_bars", interpolate=False)
xmin, xmax = ax.get_xlim()
x = np.linspace(xmin, xmax, sines.shape[1])
out, _ = optimize.leastsq(lambda p: sines.mean(0) - (np.sin(x / p[1]) + p[0]), (0, 2))
a, b = out
xx = np.linspace(xmin, xmax, 100)
plt.plot(xx, np.sin(xx / b) + a, c="#444444")

plt.title("Seaborn tsplot with CI in bokeh.")

output_file("seaborn_errorbar.html", title="seaborn_errorbar.py example")

#原來用plt.show()去產(chǎn)生圖片
#plt.show()

show(mpl.to_bokeh())

可以看到之前我用plt.show() 去產(chǎn)生圖片,現(xiàn)在可以直接用show(mpl.to_bokeh()) .只要改動(dòng)一行代碼就可以了!

Flask 中的使用

一個(gè)例子, python:

'''This example demonstrates embedding a standalone Bokeh document
into a simple Flask application, with a basic HTML web form.

To view the example, run:

    python simple.py

in this directory, and navigate to:

    http://localhost:5000

'''
from __future__ import print_function

import flask

from bokeh.embed import components
from bokeh.plotting import figure
from bokeh.resources import INLINE
from bokeh.util.string import encode_utf8

app = flask.Flask(__name__)

colors = {
    'Black': '#000000',
    'Red':   '#FF0000',
    'Green': '#00FF00',
    'Blue':  '#0000FF',
}

def getitem(obj, item, default):
    if item not in obj:
        return default
    else:
        return obj[item]

@app.route("/")
def polynomial():
    """ Very simple embedding of a polynomial chart

    """

    # Grab the inputs arguments from the URL
    args = flask.request.args

    # Get all the form arguments in the url with defaults
    color = getitem(args, 'color', 'Black')
    _from = int(getitem(args, '_from', 0))
    to = int(getitem(args, 'to', 10))

    # Create a polynomial line graph with those arguments
    x = list(range(_from, to + 1))
    fig = figure(title="Polynomial")
    fig.line(x, [i ** 2 for i in x], color=colors[color], line_width=2)

    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()

    script, div = components(fig)
    html = flask.render_template(
        'embed.html',
        plot_script=script,
        plot_div=div,
        js_resources=js_resources,
        css_resources=css_resources,
        color=color,
        _from=_from,
        to=to
    )
    return encode_utf8(html)

if __name__ == "__main__":
    print(__doc__)
    app.run()

embed.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset='utf-8' />
    <meta http-equiv='content-type' content='text/html; charset=utf-8' />

    <title>Embed Demo</title>

    {{ js_resources|indent(4)|safe }}

    {{ css_resources|indent(4)|safe }}

    {{ plot_script|indent(4)|safe }}

  </head>
  <body>
    <!-- A simple form for changing the graph -->
    <p> Select your settings: </p>
    <form name="color_button" method='GET'>
        Color:
        <select name="color">
            <option {{ "selected" if color|indent(4)|safe == "Red" }} value="Red">Red</option>
            <option {{ "selected" if color|indent(4)|safe == "Green" }} value="Green">Green</option>
            <option {{ "selected" if color|indent(4)|safe == "Blue" }} value="Blue">Blue</option>
            <option {{ "selected" if color|indent(4)|safe == "Black" }} value="Black">Black</option>
        </select>
        <br>
        From:
        <input type="text" name="_from" value="{{ _from }}">
        <br>
        To:
        <input type="text" name="to" value="{{ to }}">
        <br>
        <button type="submit">Submit</button>
    </form>
    {{ plot_div|indent(4)|safe }}
    <p> Demonstrates some very simple embedding into a webpage</p>
  </body>
</html>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容