django我爱编程计算机@linux_python_R 技术帖

Bokeh 初探

2017-03-14  本文已影响717人  Sank

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

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

安装

bokeh需要这几个库:

最方便的方式还是在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 库下面支持下面的几种渲染类型:

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>

上一篇下一篇

猜你喜欢

热点阅读