Bokeh 初探

作者: Sank | 来源:发表于2017-03-14 18:22 被阅读717次

    之前本来想想研究下 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>
    
    

    相关文章

      网友评论

        本文标题:Bokeh 初探

        本文链接:https://www.haomeiwen.com/subject/alxhnttx.html