Есть ли альтернатива для запуска сервера bokeh через bokeh serve --show? - PullRequest
1 голос
/ 18 апреля 2019

Я недавно построил панель инструментов, включающую виджеты боке. Каждый раз, когда я запускаю его, мне нужно перейти к приглашению anaconda и набрать

подача боке --show myapp.py

Есть ли более удобный способ сделать это, не открывая окно cmd? Я в настоящее время на Windows 7 и скоро будет обновлен до Windows 10.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 18 апреля 2019

А вот запрошенный код, преобразованный из примера фильмов Bokey (Bokeh v1.1.0):

from tornado.ioloop import IOLoop
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler

from os.path import dirname, join
import numpy as np
import pandas.io.sql as psql
import sqlite3 as sql
from bokeh.plotting import figure
from bokeh.layouts import layout, column
from bokeh.models import ColumnDataSource, Div
from bokeh.models.widgets import Slider, Select, TextInput
from bokeh.io import curdoc
from bokeh.sampledata.movies_data import movie_path

def make_document(doc):
    conn = sql.connect(movie_path)
    query = open(join(dirname(__file__), 'query.sql')).read()
    movies = psql.read_sql(query, conn)

    movies["color"] = np.where(movies["Oscars"] > 0, "orange", "grey")
    movies["alpha"] = np.where(movies["Oscars"] > 0, 0.9, 0.25)
    movies.fillna(0, inplace = True)  # just replace missing values with zero
    movies["revenue"] = movies.BoxOffice.apply(lambda x: '{:,d}'.format(int(x)))

    with open(join(dirname(__file__), "razzies-clean.csv")) as f:
        razzies = f.read().splitlines()
    movies.loc[movies.imdbID.isin(razzies), "color"] = "purple"
    movies.loc[movies.imdbID.isin(razzies), "alpha"] = 0.9

    axis_map = {
        "Tomato Meter": "Meter",
        "Numeric Rating": "numericRating",
        "Number of Reviews": "Reviews",
        "Box Office (dollars)": "BoxOffice",
        "Length (minutes)": "Runtime",
        "Year": "Year",
    }

    desc = Div(text = open(join(dirname(__file__), "description.html")).read(), width = 800)

    # Create Input controls
    reviews = Slider(title = "Minimum number of reviews", value = 80, start = 10, end = 300, step = 10)
    min_year = Slider(title = "Year released", start = 1940, end = 2014, value = 1970, step = 1)
    max_year = Slider(title = "End Year released", start = 1940, end = 2014, value = 2014, step = 1)
    oscars = Slider(title = "Minimum number of Oscar wins", start = 0, end = 4, value = 0, step = 1)
    boxoffice = Slider(title = "Dollars at Box Office (millions)", start = 0, end = 800, value = 0, step = 1)
    genre = Select(title = "Genre", value = "All",
                   options = open(join(dirname(__file__), 'genres.txt')).read().split())
    director = TextInput(title = "Director name contains")
    cast = TextInput(title = "Cast names contains")
    x_axis = Select(title = "X Axis", options = sorted(axis_map.keys()), value = "Tomato Meter")
    y_axis = Select(title = "Y Axis", options = sorted(axis_map.keys()), value = "Number of Reviews")

    # Create Column Data Source that will be used by the plot
    source = ColumnDataSource(data = dict(x = [], y = [], color = [], title = [], year = [], revenue = [], alpha = []))

    TOOLTIPS = [
        ("Title", "@title"),
        ("Year", "@year"),
        ("$", "@revenue")
    ]

    p = figure(plot_height = 600, plot_width = 700, title = "", toolbar_location = None, tooltips = TOOLTIPS)
    p.circle(x = "x", y = "y", source = source, size = 7, color = "color", line_color = None, fill_alpha = "alpha")

    def select_movies():
        genre_val = genre.value
        director_val = director.value.strip()
        cast_val = cast.value.strip()
        selected = movies[
            (movies.Reviews >= reviews.value) &
            (movies.BoxOffice >= (boxoffice.value * 1e6)) &
            (movies.Year >= min_year.value) &
            (movies.Year <= max_year.value) &
            (movies.Oscars >= oscars.value)
        ]
        if (genre_val != "All"):
            selected = selected[selected.Genre.str.contains(genre_val) == True]
        if (director_val != ""):
            selected = selected[selected.Director.str.contains(director_val) == True]
        if (cast_val != ""):
            selected = selected[selected.Cast.str.contains(cast_val) == True]
        return selected

    def update():
        df = select_movies()
        x_name = axis_map[x_axis.value]
        y_name = axis_map[y_axis.value]

        p.xaxis.axis_label = x_axis.value
        p.yaxis.axis_label = y_axis.value
        p.title.text = "%d movies selected" % len(df)
        source.data = dict(
            x = df[x_name],
            y = df[y_name],
            color = df["color"],
            title = df["Title"],
            year = df["Year"],
            revenue = df["revenue"],
            alpha = df["alpha"],
        )

    controls = [reviews, boxoffice, genre, min_year, max_year, oscars, director, cast, x_axis, y_axis]
    for control in controls:
        control.on_change('value', lambda attr, old, new: update())

    inputs = column(*controls)
    l = layout([
        [desc],
        [inputs, p],
    ])

    update()  # initial load of the data

    doc.add_root(l)
    doc.title = "Movies"

io_loop = IOLoop.current()
server = Server(applications = {'/': Application(FunctionHandler(make_document))}, io_loop = io_loop, port = 5001)
server.start()
server.show('/')
io_loop.start()
0 голосов
/ 18 апреля 2019

Это объясняется здесь в документации Bokeh: Запуск сервера Bokeh

А вот один пример для Bokeh v1.1.0:

from tornado.ioloop import IOLoop
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource
import random

def make_document(doc):
    source = ColumnDataSource({'x': [], 'y': [], 'color': []})

    def update():
        new = {'x': [random.random()], 'y': [random.random()], 'color': [random.choice(['red', 'blue', 'green'])]}
        source.stream(new)

    doc.add_periodic_callback(update, 1000)

    fig = figure(title = 'Streaming Circle Plot!', x_range = [0, 1], y_range = [0, 1])
    fig.circle(source = source, x = 'x', y = 'y', color = 'color', size = 10)

    doc.title = "Now with live updating!"
    doc.add_root(fig)

apps = {'/': Application(FunctionHandler(make_document))}

io_loop = IOLoop.current()
server = Server(applications = {'/': Application(FunctionHandler(make_document))}, io_loop = io_loop, port = 5001)
server.start()
server.show('/')
io_loop.start()
...