On Jul 5, 2016, at 12:05 PM, 'Tina Wenzel' via Bokeh Discussion - Public <[email protected]> wrote:
Hi Bryan,
Yes, that helped. The tabs show up now, Thank you.
I still have a problem with the widgets. I still want widgets to display on all tabs and hence tried to add the same widgets as on tab1 (called inputs) to the tab2. If I try that it does not display anymore.
I tried to change the name to inputs2 instead:
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
# inputs2 = widgetbox(*controls, sizing_mode=sizing_mode)
l1 = layout([[desc],
[inputs, p],
[w4], ], sizing_mode=sizing_mode)
# l2 = layout([[inputs2,w5], ], sizing_mode=sizing_mode)
# moved from earlier in the script. Put the layout in one of the tabs panels, and a table in the other
tab1 = Panel(child=l1, title="plot")
tab2 = Panel(child=w5, title="datatable")
# tab2 = Panel(child=l2, title="datatable")
tabs = Tabs(tabs=[tab1, tab2])
This did not work however.
Any idea how to do that? I have pasted the updated app below.
Many Thanks & Regards,
from os.path import dirname, join
from bokeh.models.widgets import Slider,CheckboxGroup,DataTable,MultiSelect,TableColumn
import numpy as np
import pandas.io.sql as psql
import sqlite3 as sql
from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource, HoverTool, Div
from bokeh.models.widgets import Slider, Select, TextInput,DataTable
from bokeh.io import curdoc
from bokeh.sampledata.movies_data import movie_path
from bokeh.embed import components
from bokeh.models.widgets import Panel, Tabs
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=))
columns = [
TableColumn(field="name", title="Name"),
TableColumn(field="x", title="X"),
TableColumn(field="y", title="Y"),
]
hover = HoverTool(tooltips=[
("Title", "@title"),
("Year", "@year"),
("$", "@revenue")
])
p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None, tools=[hover])
p.circle(x="x", y="y", source=source, size=7, color="color", line_color=None, fill_alpha="alpha")
w4 = DataTable(source=source, columns=columns, height=280)
w5 = DataTable(source=source, columns=columns, height=280)
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())
sizing_mode = 'fixed' # 'scale_width' also looks nice with this example
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
# inputs2 = widgetbox(*controls, sizing_mode=sizing_mode)
l1 = layout([[desc],
[inputs, p],
[w4], ], sizing_mode=sizing_mode)
# l2 = layout([[inputs2,w5], ], sizing_mode=sizing_mode)
# moved from earlier in the script. Put the layout in one of the tabs panels, and a table in the other
tab1 = Panel(child=l1, title="plot")
tab2 = Panel(child=w5, title="datatable")
# tab2 = Panel(child=l2, title="datatable")
tabs = Tabs(tabs=[tab1, tab2])
update() # initial load of the data
# add tabs as a root
curdoc().add_root(tabs)
curdoc().title = "Movies"
Am Dienstag, 5. Juli 2016 15:00:04 UTC+1 schrieb Bryan Van de ven:
Hi, a couple of notes:
In the code below, you create a Tabs object, but then it never gets added to the document. It's also worth mentioning that the same plot cannot currently be added twice (e.g. the exact same plot object in two tabs or columns, etc.) I am not entirely sure about your goals but I did make this small re-arrangement to get a working Tabs:
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
l = layout([ [desc], [inputs, p], ], sizing_mode=sizing_mode)
# moved from earlier in the script. Put the layout in one of the tabs panels, and a table in the other
tab1 = Panel(child=l, title="plot")
tab2 = Panel(child=w4, title="datatable")
tabs = Tabs(tabs=[ tab1, tab2 ])
update() # initial load of the data
# add tabs as a root
curdoc().add_root(tabs)
curdoc().title = "Movies"
Hopefully this helps some,
Thanks,
Bryan
> On Jul 5, 2016, at 12:55 AM, 'Tina Wenzel' via Bokeh Discussion - Public <[email protected]> wrote:
>
> Hi,
>
> Below is my modified code of the movies example app in the bokeh library.
>
> I tried to add several tabs to it, but could not figure out how. The tabs that I added are highlighted in blue.
>
> I want all tabs to look like the main page: widgets on the left, graph and table vertically aligned on the right.
>
> How could I add a few tabs within this template?
>
> Many Thanks & Regards,
>
>
> from os.path import dirname, join
> from bokeh.models.widgets import Slider,CheckboxGroup,DataTable,MultiSelect,TableColumn
>
> import numpy as np
> import pandas.io.sql as psql
> import sqlite3 as sql
>
> from bokeh.plotting import figure
> from bokeh.layouts import layout, widgetbox
> from bokeh.models import ColumnDataSource, HoverTool, Div
> from bokeh.models.widgets import Slider, Select, TextInput,DataTable
> from bokeh.io import curdoc
> from bokeh.sampledata.movies_data import movie_path
>
> from bokeh.embed import components
> from bokeh.models.widgets import Panel, Tabs
>
>
> 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=))
> columns = [
> TableColumn(field="name", title="Name"),
> TableColumn(field="x", title="X"),
> TableColumn(field="y", title="Y"),
> ]
>
> hover = HoverTool(tooltips=[
> ("Title", "@title"),
> ("Year", "@year"),
> ("$", "@revenue")
> ])
>
> p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None, tools=[hover])
> p.circle(x="x", y="y", source=source, size=7, color="color", line_color=None, fill_alpha="alpha")
>
> w4 = DataTable(source=source, columns=columns, height=280)
>
> tab1 = Panel(child=p, title="plot")
> tab2 = Panel(child=w4, title="datatable")
>
> 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())
>
> sizing_mode = 'fixed' # 'scale_width' also looks nice with this example
>
> inputs = widgetbox(*controls, sizing_mode=sizing_mode)
>
> tabs = Tabs(tabs=[ tab1, tab2 ])
>
> l = layout([
> [desc],
> [inputs, p],
> [w4],
> ], sizing_mode=sizing_mode)
>
> update() # initial load of the data
>
> curdoc().add_root(l)
> curdoc().title = "Movies"
>
>
> --
> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+un...@continuum.io.
> To post to this group, send email to bo...@continuum.io.
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CAFgg%2BiePfBEOZ9LND_Ry_4%2Ba_yvDwU4uumVfeL2yvOAm_F%3Dk2A%40mail.gmail.com\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/a2a9cf40-9229-4c9f-adc5-016deda03cfe%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.