Bokeh 初探

之前本来想想研究下 pandas+highchart 的解决方案,网上搜了下发现Bokeh 这个好东西,简单易用,天然就是支持python 和 pandas。而且很多场合都能用 (可以纯python用,可以在jupyter里面用,可以和flask结合用,甚至有自己的bokeh server), 挺有意思的

官方网址: http://bokeh.pydata.org/en/latest/
Github: https://github.com/bokeh/bokeh

安装

bokeh需要这几个库:

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

最方便的方式还是在anacode 下面安装, 用这个命令 conda install bokeh

简单的例子

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 中的使用

先导入下面的package. from bokeh.io import push_notebook, show, output_notebook, 再用 output_notebook() 设置输出在jupyter notebook里面。( 一般情况是用output_file()输出为html文件。) 这样还不够, 还需要在show()函数设置 notebook_hanlde 参数为True
下面是个官方的例子:

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() 函数更新上面的渲染的图像。在上面的代码后建新的cell:

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

运行完后可以发现上面cell的输出图像变化了。

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

chart 库 + pandas

如何方便的bokeh去快速渲染pandas的数据呢, 用chart, chart 库的使用说明可以去http://bokeh.pydata.org/en/latest/docs/reference/charts.html

简而言之,chart 库下面支持下面的几种渲染类型:

  • Area
  • Bar
  • BoxPlot
  • Chord
  • Donut
  • HeatMap
  • Horizon
  • Line
  • Scatter
  • Step
  • TimeSeries
    一个例子:
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的数据

mpl 库

我之前其实已经有用matplotlib.pyplot 库去产生图片了,mpl库提供了一个快速替换的方法。

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()去产生图片
#plt.show()

show(mpl.to_bokeh())

可以看到之前我用plt.show() 去产生图片,现在可以直接用show(mpl.to_bokeh()) .只要改动一行代码就可以了!

Flask 中的使用

一个例子, 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>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容