ScottP
ScottP

Reputation: 107

How to create a multi_line plot with HoverTool using Bokeh?

From a Pandas dataframe like the one below, I'm simply trying to create a multi_line plot plus HoverTool; however, I can't find any examples similar to my specific case. Here is my sample code:

import pandas as pd
import numpy as np

# Dataframe (just toy data, this will be an import of a much larger dataset)
index = ['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', 
         '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31']

columns = ['Argentina', 'Turkey', 'Mexico']

np.random.seed(123)
data = np.random.rand(10, 3)

df = pd.DataFrame(index=index, columns=columns, data=data)
df.index = pd.to_datetime(df.index)
df.index.name = 'Date'

# Attempt at plot (obviously doesn't work)
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.io import output_notebook, show
output_notebook()

source = ColumnDataSource(df)

p = figure(plot_height=400)
p.multi_line(xs='Date', ys=columns, source=source)

p.add_tools(HoverTool(tooltips=[('Country', '@???'),
                                ('Date', '@Date'),
                                ('Value', '@???')]))

show(p)

enter image description here

Upvotes: 0

Views: 424

Answers (1)

Jasper
Jasper

Reputation: 1795

Multi lines xs and ys should be a list of lists, that's why it didn't work. I replaced the multiline for 3 normal lines and it should work fine now. If you really want to use multi line, you should format your data like this:

index = ['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', 
         '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31']
source = ColumnDataSource(dict(
"xs": [index, index, index],
"ys": np.random.rand(3, 10).tolist()
)) 

Working code with line instead of multiline:

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.io import output_notebook, show
import pandas as pd
import numpy as np

index = ['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', 
         '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31']

columns = ['Argentina', 'Turkey', 'Mexico']

np.random.seed(123)
data = np.random.rand(10, 3)

df = pd.DataFrame(index=index, columns=columns, data=data)
df['Date'] = index

output_notebook() 
source = ColumnDataSource(df)

p = figure(plot_height=400, x_range=index)
p.line(x='Date', y='Argentina', source=source, color='red', legend='Argentina ', name='Argentina')
p.line(x='Date', y='Turkey', source=source, color='blue', legend='Turkey ', name='Turkey')
p.line(x='Date', y='Mexico', source=source, color='green', legend='Mexico ', name='Mexico')
p.xaxis.major_label_orientation = 0.90
p.legend.click_policy="hide"
p.add_tools(HoverTool(tooltips=[('Country', '$name'),
                                ('Date', '@Date'),
                                ('Value', '$y')]))

show(p)

Version with multiline:

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.io import show, output_notebook
import pandas as pd
import numpy as np

index = ['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', 
         '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31']

columns = ['Argentina', 'Turkey', 'Mexico']

np.random.seed(123)
data = np.random.rand(10, 3)
df = pd.DataFrame(index=index, columns=columns, data=data)
df_transposed = df.transpose()
source = ColumnDataSource({"xs": [df.index.values.tolist()]*len(list(df.columns.values)), "ys": df_transposed.values.tolist(), "colors": ["red", "green", "blue"], "names": list(df.columns.values)})

output_notebook()
p = figure(plot_height=400, x_range=index)
p.multi_line(xs='xs', ys='ys', color = "colors", name="names", legend="names", source=source)
p.xaxis.major_label_orientation = 0.90
p.legend.click_policy="hide"
p.add_tools(HoverTool(tooltips=[('Country', '@names'),
                                ('Date', '$x'),
                                ('Value', '$y')]))

show(p)

I only had one problem with the hover tool. It doesn't display the correct date. (Now it shows the x position, if I replaced this for "xs" it would show the whole date list)

Upvotes: 2

Related Questions