ich versuche, mehrere Scatterglyphen mit Hilfe einer Schleife in einen Plot zu bekommen. Das Ziel ist es, für jede Marke (brand) eine eigene Glyphe zu verwenden und die Werte zu aktualisieren, wenn ein anderer Wert von den Select-Widgets (Wert x-Achse, Wert -Achse) gewählt wird.
Hintergrund ist, dass ich später eine "Interactive Legend" erstellen möchte, bei der man durch klick auf enen Eintrag den Graphen "verstecken" kann.
Das man mehrere Graphen/Glyphen in einen Plot bekommt habe ich ohne Schleife schon hinbekommen, s. auch hier: https://docs.bokeh.org/en/latest/docs/g ... ght=legend
Die Interaktive Legende wird hier beschrieben: https://docs.bokeh.org/en/latest/docs/u ... ght=legend
Die Abbildung zeigt jedoch ein leeres Diagramm, bzw nur den letzten Graphen aus der Schleife. Ich gehe davon aus, dass das Problem die ColumnDataSource und die Aktualisierung in der Funktion "update()" ist. Unten findet Ihr ein ausführbares Beispiel (Ich verwende eigentlich einen Bokeh server, habe hier aber ein Ausführbares Beispiel gepostet, daher kommt die Warnung mit NodeJS und Bokehserver).
Habt Ihr eine Idee? Vielen Dank für Eure Hilfe!
Code: Alles auswählen
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Select, HoverTool
from bokeh.plotting import figure, show
import pandas as pd
brands = ['a', 'b', 'c', 'a', 'b', 'b', 'c']
product = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7']
price = [2, 3, 54, 48, 9, 2, 4]
size = [10, 11, 12, 13, 14, 15, 16]
value = [5, 4, 3, 8, 1, 0, 1]
id = [1, 2, 3, 4, 5, 6, 7]
col = ['ID', 'brand', 'product', 'price', 'size', 'value']
label = ['price', 'size', 'value']
df = pd.DataFrame(zip(brands, product, price, size, value, id), columns=col)
# Widgets:
select_x_axis = Select(title="x-Axis:", value=label[0], options=label)
select_y_axis = Select(title="y-Axis:", value=label[1], options=label)
# Set up figure
hover = HoverTool(tooltips=[
("index", "@id"),
('Brand', '@brand'),
('Product', '@product'),
(select_x_axis.value, '@x'),
(select_y_axis.value, '@y')
])
# Set up plots:
fig = figure(plot_height=400, plot_width=800, title="xyz",
# tooltips=TOOLTIPS,
tools=[hover, 'reset'],
x_axis_label=select_x_axis.value,
y_axis_label=select_y_axis.value)
source = {}
plots = {}
for brand in brands:
# Create Column Data Source that will be used by the plot
source[brand] = ColumnDataSource(data=dict(x=[], y=[], id=[], product=[], brand=[]))
plots[brand] = fig.scatter(x='x', y='y', size=5, source=source[brand])
def update():
x_name = select_x_axis.value
y_name = select_y_axis.value
fig.xaxis.axis_label = x_name
fig.yaxis.axis_label = y_name
for brand in brands:
df1 = df.loc[df['brand'] == brand]
source[brand].data = dict(
x=df1[x_name],
y=df1[y_name],
id=df1['ID'],
product=df1['product'],
brand=df1['brand']
)
# Set up layouts and add to document
controls = [select_x_axis, select_y_axis]
for control in controls:
control.on_change('value', lambda attr, old, new: update())
inputs = column(select_x_axis, select_y_axis)
update() # initial load of the data
show(row(inputs, fig, width=1000))
#curdoc().add_root(row(inputs, fig, width=1000))
#curdoc().title = "xyz"