散景:根据源列数据动态更改轴类型(垂直或标称)

时间:2018-11-15 17:17:24

标签: python bokeh

我正在创建一个交互式散点图,其中包括x和y轴的下拉列表。

但是,当前仅当x和y轴源列是数字或日期对象等时才起作用。对于字符串列,则什么都不会显示。

如何更改脚本,使其根据当前下拉菜单自动将轴类型从标称更改为序数,反之亦然?

# -*- coding: utf-8 -*-

from os.path import dirname, join
import numpy as np
import pandas.io.sql as psql
import sqlite3 as sql
import pandas as pd

from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource, Div
from bokeh.models.widgets import Slider, Select, TextInput
from bokeh.io import curdoc

projects = pd.read_excel('explorer_data.xlsx')

#functions
year = lambda x : x.to_pydatetime().year

axis_map = {header:header for header in list(projects)}

# Create Input controls
budget = Slider(title="Minimum budget", value=80, start=0, end=200000, step=1000)
start_date = Slider(title="Project start date", start=1940, end=2019, value=1970, step=1)
end_date = Slider(title="Project end date", start=1940, end=2019, value=2019, step=1)

x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Budget")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Spent/Paid")

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

TOOLTIPS=[
    ("ID", "@number")
#    ("Year", "@year"),
#    ("$", "@revenue")
]

p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None, tools = "pan,wheel_zoom,box_zoom,reset", tooltips=TOOLTIPS)
p.circle(x="x", y="y", source=source, size=7)

def select_projects():
    selected = projects[

        (projects['Budget'] >= budget.value) &
        (projects['Start Date'].map(year) >=  start_date.value) &
        (projects['End Date'].map(year) <= end_date.value)
    ]

    return selected


def update():
    df = select_projects()
    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 projects selected" % len(df)
    source.data = dict(
        x=df[x_name],
        y=df[y_name],
        number=df['Project ID'],
    )

controls = [budget, start_date, end_date, x_axis, y_axis]
for control in controls:
    control.on_change('value', lambda attr, old, new: update())

sizing_mode = 'fixed'  # 'scale_width' also looks nice with this example

inputs = widgetbox(*controls, sizing_mode=sizing_mode)
l = layout([
#    [desc],
    [inputs, p],
], sizing_mode=sizing_mode)

update()  # initial load of the data

curdoc().add_root(l)
curdoc().title = "Projects"

0 个答案:

没有答案