Anamaria
Anamaria

Reputation: 51

Python Bokeh - interactive legend hiding glyphs - not working

I try to implement Bokeh interactive legend, to filter the data plotted based on user selection. I need some help to figure out what is wrong with my code; I get the some glyphs for each use, different color (see the images bellow).

#Import libraries
from bokeh.io import output_notebook, show
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import figure
from bokeh.palettes import Category20_20
import pandas as pd

output_notebook()
#Create the dataframe
df = pd.DataFrame({'Index': ['9', '10', '11', '12', '13'],
        'Size': ['25', '15', '28', '43', '18'], 
        'X': ['751', '673', '542', '362', '224'],
        'Y': ['758', '616', '287', '303', '297'],
        'User': ['u1', 'u1', 'u2', 'u2', 'u2'],
        'Location': ['A', 'B', 'C', 'C', 'D'], 
        })

# Create plot

p = figure(plot_width=450, plot_height=450)
p.title.text = 'Title....'

users=list(set(df['User']))
size=df['Size']
for data, name, color in zip(df, users, Category20_20):
    p.circle(x=df['X'], y=df['Y'], size=size, color=color, alpha=0.8, legend=name)

p.legend.location = "top_left"
p.legend.click_policy="hide"

show(p)

enter image description here enter image description here

Upvotes: 0

Views: 855

Answers (1)

Eugene Pakhomov
Eugene Pakhomov

Reputation: 10697

In this loop

for data, name, color in zip(df, users, Category20_20):
    p.circle(x=df['X'], y=df['Y'], size=size, color=color, alpha=0.8, legend=name)

you're:

  • Iterating over column names of the data frame (because Pandas is very confusing in this regard), so your number of points will be limited (because zip stops at the shortest collection)
  • Not using data
  • Passing full data to p.circle, meaning you have two sets of circles that have completely identical coordinates and sizes
  • Using the legend keyword, which is deprecated

Instead, try this:

users=list(set(df['User']))
for name, color in zip(users, Category20_20):
    user_df = df[df['User'] == name]
    p.circle(x=user_df['X'], y=user_df['Y'], size=user_df['Size'],
             color=color, alpha=0.8, legend_label=name)

Upvotes: 1

Related Questions