Make dropdown selection responsive for y axis Altair python - python

I have several columns (eg, Column, y1, y2, y3..) that I need to relate to column "X" on a scatter plot in Altair. I have included a dropdown combo box to make the selection between the "y" columns however the plots fail to change according to the selection. How can I make the y-axis selection responsive? Here is the code
# CHART 1
input_dropdown = alt.binding_select(options = \
np.array(df.drop(["Student IDs", "Average Marks"],
axis = 1).columns),
name = "Module")
selection = alt.selection_single(bind = input_dropdown)
# plot the first chart
chart1 = alt.Chart(df).mark_point().encode(
x = "Average Marks",
y = "CSE103"
).add_selection(
selection)
chart1

This is not directly supported in Vega-Lite, you can add your thumbs up and subscribe to this issue to find out when/if it is implemented https://github.com/vega/vega-lite/issues/7365.
In the meantime, you could workaround it using the same approach as in Altair heatmap with dropdown variable selector, where the data frame is first melted (but you can't dynamically change the axis title).
import altair as alt
from vega_datasets import data
df = data.cars().melt(id_vars=['Origin', 'Name', 'Year', 'Horsepower'])
dropdown_options = df['variable'].drop_duplicates().tolist()
dropdown = alt.binding_select(options=dropdown_options, name='X-axis column ')
selection = alt.selection_single(
fields=['variable'],
init={'variable': dropdown_options[0]},
bind=dropdown
)
alt.Chart(df).mark_circle().encode(
x=alt.X('value:Q', title=''),
y='Horsepower',
color='Origin',
).add_selection(
selection
).transform_filter(
selection
)

Related

Add formatting, surrounding box to Altair vertical line tooltip label?

I am new to Altair, and am attempting to plot a monthly time-series variable, and have a vertical line tooltip display the date and corresponding y-value.
The code I have (warning, probably a bit ugly) gets me most of the way there:
import altair as alt
import datetime as dt
import numpy as np
import pandas as pd
# create DataFrame
monthly_dates = pd.date_range('1997-09-01', '2022-08-01', freq = 'M')
monthly_data = pd.DataFrame(
index=['Date', 'y_var'],
data=[monthly_dates, np.random.normal(size = len(monthly_dates))]
).T
# Create a selection that chooses the nearest point & selects based on x-value
nearest = alt.selection(type='single', nearest=True, on='mouseover',
fields=['Date'], empty='none')
# The basic line
line = alt.Chart(monthly_data).mark_line().encode(
x='Date:T',
y=alt.Y('y_var', title='Y variable')
)
# Transparent selectors across the chart. This is what tells us
# the x-value of the cursor
selectors = alt.Chart(monthly_data).mark_point().encode(
x='Date',
opacity=alt.value(0),
).add_selection(
nearest
)
# Draw points on the line, and highlight based on selection
points = line.mark_point().encode(
opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)
# Draw text labels near the points, and highlight based on selection
text_x = line.mark_text(align='left', dx=5, dy=-10).encode(
text=alt.condition(nearest, 'Date', alt.value(' '))
)
# Draw text labels near the points, and highlight based on selection
text_y = line.mark_text(align='left', dx=5, dy=5).encode(
text=alt.condition(nearest, 'y_var', alt.value(' '))
).transform_calculate(label='datum.y_var + "%"')
# Draw a rule at the location of the selection
rules = alt.Chart(monthly_data).mark_rule(color='gray').encode(
x='Date',
).transform_filter(
nearest
)
# Put the seven layers into a chart and bind the data
chart = alt.layer(
line, selectors, points, rules, text_x, text_y
).properties(
width=600, height=300
).interactive()
chart.show()
yields the following interactive chart:
There are two things I need to do, though:
Add a box around the tooltip labels (and a plain background to this box), so that they are easy to read.
Format the labels independently: since we have monthly data, it would be great to drop the day and just have Oct 2008 or 2008-10 or something along those lines. For the value, rounding to one or two digits and adding '%' afterwards would be great. I tried using the example found here (as you can see for creating text_y) but to no avail.
Any and all help would be greatly appreciated. Apologies in advance for any dumb mistakes or poor coding practices; again, I am still learning the basics of Altair.
Update: I figured both out.
The solutions to both 1 and 2 are in the code below.
For 1: instead of trying to add a box around the text manually, I instead added tooltips to the selectors object and dropped the text_x and text_y entirely.
For 2: I used transform_calculate to create new fields for x_label and y_label that are exactly what I want to display, then feed these into the tooltip objects. This page has tons of ways to transform data.
selectors = alt.Chart(monthly_data).mark_point().transform_calculate(
x_label='timeFormat(datum.Date, "%b %Y")',
y_label='format(datum.y_var, ".1f") + "%"'
).encode(
x='Date',
opacity=alt.value(0),
tooltip=[
alt.Tooltip('x_label:N', title='Date'),
alt.Tooltip('y_label:N', title='Pct. Change')
]
).add_selection(
nearest
)
The finished product:

Altair choropleth map, color highlight based on line chart selection

I am plotting a choropleth map colored by the field Passenger_0_ and a line chart showing the evolution of Passenger_0_ throughout a day by zone.
I would like to select a line (zone) in the line chart and have it highlighted in the map and vice versa (select a zone in the map and have it highlighted in the line chart).
For now, I am able to change the whole color of the map when selecting the line, but have no clue of how to only change the color of the selected area.
I would appreciate any help.
In order to reproduce the sample you need to download these two files:
output_data.csv
taxi_zones.geojson
Then run this piece of code to get a GeoDataFrame named long_df:
import altair as alt
import pandas as pd
import geopandas as gpd
import json
geo_json_file_loc= './taxi_zones.geojson'
with open(geo_json_file_loc) as json_data:
data = json.load(json_data)
gdf = gpd.GeoDataFrame.from_features((data))
gdf = gdf[gdf['borough']=='Manhattan']
gdf = gdf[['location_id','zone','geometry']]
gdf = gdf.rename(columns={'location_id':'LocationID'})
gdf['LocationID'] = pd.to_numeric(gdf['LocationID'])
output_data = pd.read_csv('./output_data.csv',sep=',')
def load_taxis_data(output_data, shape_data):
df_to_visualize = shape_data.copy()
pickups = output_data.groupby(['hour','dayofweek','LocationID']).sum()
listofdays = pd.unique(output_data['dayofweek'])
for hour in range(24):
for dayofweek in listofdays:
# get pickups for this hour and weekday
p = pd.DataFrame(pickups.loc[(hour, dayofweek)]).reset_index()
# add pickups to the Taxi Zones DataFrame
df_to_visualize = pd.merge(df_to_visualize, p, on="LocationID", how="left").fillna(0)
# rename column as per day and hour
df_to_visualize.rename(columns={"pickups" : "Passenger_%d_%d"%(dayofweek, hour)}, inplace=True)
return df_to_visualize
gdf_merged = load_taxis_data(output_data, gdf)
# drop unwanted days
for hour in range(24):
for dayofweek in [5,6]:
column_to_drop = "Passenger_%d_%d"%(dayofweek, hour)
gdf_merged.drop([column_to_drop], axis=1, inplace=True)
gdf_merged.reset_index(level=0, inplace=True)
long_df = pd.wide_to_long(gdf_merged, ["Passenger_0_"], i='index', j="hour")
long_df = long_df.reset_index()
Once you got long_df this is the code for the plots:
dict_json = json.loads(long_df[long_df['hour']==0].to_json())
colours_obj = alt.Color('properties.Passenger_0_:Q',
scale=alt.Scale(scheme='yelloworangered'),
title = "Pickups")
sel_line_hover = alt.selection_single(on='mouseover', empty='none')
sel_line_col = alt.selection_single()
sel_line_size = alt.selection_single(empty='none')
base = alt.Chart(alt.Data(values=dict_json['features'])).mark_geoshape(
stroke='black',
strokeWidth=1
).encode(
color=alt.condition(sel_line_col, colours_obj, alt.value('lightgray')),
tooltip = ['properties.zone:O',
'properties.Passenger_0_:Q']
).properties(
width=350,
height=750,
).add_selection(
sel_line_col
)
line = alt.Chart(long_df).mark_line().encode(
x='hour',
y='Passenger_0_',
color=alt.condition(sel_line_hover|sel_line_col, 'zone', alt.value('lightgray')),
size=alt.condition(sel_line_hover|sel_line_size, alt.value(4),alt.value(1)),
tooltip = ['zone:O']
).properties(
width=250,
height=750,
).add_selection(
sel_line_hover,sel_line_col,sel_line_size
)
base | line
And this is what the plot does:
Thank you in advance for your help!
Here is a general example of how to achieve two-way interactivity in Altair, using data from the sample repos only. The key is to set the feature that should be filtered by the selection even via fields parameter when creating the selection. Then you add this selection and the corresponding condition to the same encoding of both the plots.
import altair as alt
from vega_datasets import data
state_pop = data.population_engineers_hurricanes()[['state', 'id', 'population']]
state_map = alt.topo_feature(data.us_10m.url, 'states')
click = alt.selection_multi(fields=['state'])
choropleth = (alt.Chart(state_map).mark_geoshape().transform_lookup(
lookup='id',
from_=alt.LookupData(state_pop, 'id', ['population', 'state']))
.encode(
color='population:Q',
opacity=alt.condition(click, alt.value(1), alt.value(0.2)),
tooltip=['state:N', 'population:Q'])
.add_selection(click)
.project(type='albersUsa'))
bars = (
alt.Chart(
state_pop.nlargest(15, 'population'),
title='Top 15 states by population').mark_bar().encode(
x='population',
opacity=alt.condition(click, alt.value(1), alt.value(0.2)),
color='population',
y=alt.Y('state', sort='x'))
.add_selection(click))
choropleth & bars

How to color lines on mouseover in a bump chart using Altair Viz?

The goal is to highlight the entire line when hovering anywhere (not just at the data points) on the line.
Imports:
from IPython.display import display
import pandas as pd
import altair as alt
Data:
data = '{"Date":{"5":1560643200000,"18":1560643200000,"22":1560643200000,"24":1560643200000,"59":1560643200000,"65":1561248000000,"78":1561248000000,"82":1561248000000,"84":1561248000000,"119":1561248000000,"125":1561852800000,"138":1561852800000,"142":1561852800000,"144":1561852800000,"179":1561852800000,"185":1562457600000,"198":1562457600000,"202":1562457600000,"204":1562457600000,"239":1562457600000,"245":1563062400000,"258":1563062400000,"262":1563062400000,"264":1563062400000,"299":1563062400000,"305":1563667200000,"318":1563667200000,"322":1563667200000,"324":1563667200000,"359":1563667200000,"365":1564272000000,"378":1564272000000,"382":1564272000000,"384":1564272000000,"419":1564272000000,"425":1564876800000,"438":1564876800000,"442":1564876800000,"444":1564876800000,"479":1564876800000,"485":1565481600000,"498":1565481600000,"502":1565481600000,"504":1565481600000,"539":1565481600000,"545":1566086400000,"558":1566086400000,"562":1566086400000,"564":1566086400000,"599":1566086400000,"605":1566691200000,"618":1566691200000,"622":1566691200000,"624":1566691200000,"659":1566691200000,"665":1567296000000,"678":1567296000000,"682":1567296000000,"684":1567296000000,"719":1567296000000,"725":1567900800000,"738":1567900800000,"742":1567900800000,"744":1567900800000,"779":1567900800000,"785":1568505600000,"798":1568505600000,"802":1568505600000,"804":1568505600000,"839":1568505600000,"845":1569110400000,"858":1569110400000,"862":1569110400000,"864":1569110400000,"899":1569110400000,"905":1569715200000,"918":1569715200000,"922":1569715200000,"924":1569715200000,"959":1569715200000,"965":1570320000000,"978":1570320000000,"982":1570320000000,"984":1570320000000,"1019":1570320000000,"1025":1570924800000,"1038":1570924800000,"1042":1570924800000,"1044":1570924800000,"1079":1570924800000,"1085":1571529600000,"1098":1571529600000,"1102":1571529600000,"1104":1571529600000,"1139":1571529600000,"1145":1572134400000,"1158":1572134400000,"1162":1572134400000,"1164":1572134400000,"1199":1572134400000,"1205":1572739200000,"1218":1572739200000,"1222":1572739200000,"1224":1572739200000,"1259":1572739200000,"1265":1573344000000,"1278":1573344000000,"1282":1573344000000,"1284":1573344000000,"1319":1573344000000,"1325":1573948800000,"1338":1573948800000,"1342":1573948800000,"1344":1573948800000,"1379":1573948800000,"1385":1574553600000,"1398":1574553600000,"1402":1574553600000,"1404":1574553600000,"1439":1574553600000,"1445":1575158400000,"1458":1575158400000,"1462":1575158400000,"1464":1575158400000,"1499":1575158400000,"1505":1575763200000,"1518":1575763200000,"1522":1575763200000,"1524":1575763200000,"1559":1575763200000,"1565":1576368000000,"1578":1576368000000,"1582":1576368000000,"1584":1576368000000,"1619":1576368000000},"Store":{"5":"store1","18":"store2","22":"store3","24":"store4","59":"store5","65":"store1","78":"store2","82":"store3","84":"store4","119":"store5","125":"store1","138":"store2","142":"store3","144":"store4","179":"store5","185":"store1","198":"store2","202":"store3","204":"store4","239":"store5","245":"store1","258":"store2","262":"store3","264":"store4","299":"store5","305":"store1","318":"store2","322":"store3","324":"store4","359":"store5","365":"store1","378":"store2","382":"store3","384":"store4","419":"store5","425":"store1","438":"store2","442":"store3","444":"store4","479":"store5","485":"store1","498":"store2","502":"store3","504":"store4","539":"store5","545":"store1","558":"store2","562":"store3","564":"store4","599":"store5","605":"store1","618":"store2","622":"store3","624":"store4","659":"store5","665":"store1","678":"store2","682":"store3","684":"store4","719":"store5","725":"store1","738":"store2","742":"store3","744":"store4","779":"store5","785":"store1","798":"store2","802":"store3","804":"store4","839":"store5","845":"store1","858":"store2","862":"store3","864":"store4","899":"store5","905":"store1","918":"store2","922":"store3","924":"store4","959":"store5","965":"store1","978":"store2","982":"store3","984":"store4","1019":"store5","1025":"store1","1038":"store2","1042":"store3","1044":"store4","1079":"store5","1085":"store1","1098":"store2","1102":"store3","1104":"store4","1139":"store5","1145":"store1","1158":"store2","1162":"store3","1164":"store4","1199":"store5","1205":"store1","1218":"store2","1222":"store3","1224":"store4","1259":"store5","1265":"store1","1278":"store2","1282":"store3","1284":"store4","1319":"store5","1325":"store1","1338":"store2","1342":"store3","1344":"store4","1379":"store5","1385":"store1","1398":"store2","1402":"store3","1404":"store4","1439":"store5","1445":"store1","1458":"store2","1462":"store3","1464":"store4","1499":"store5","1505":"store1","1518":"store2","1522":"store3","1524":"store4","1559":"store5","1565":"store1","1578":"store2","1582":"store3","1584":"store4","1619":"store5"},"Rank":{"5":1.0,"18":1.0,"22":1.0,"24":1.0,"59":1.0,"65":2.0,"78":2.0,"82":2.0,"84":2.0,"119":2.0,"125":2.0,"138":2.0,"142":2.0,"144":2.0,"179":2.0,"185":2.0,"198":2.0,"202":2.0,"204":2.0,"239":2.0,"245":2.0,"258":2.0,"262":2.0,"264":2.0,"299":2.0,"305":2.0,"318":2.0,"322":2.0,"324":2.0,"359":2.0,"365":2.0,"378":2.0,"382":2.0,"384":1.0,"419":2.0,"425":3.0,"438":1.0,"442":3.0,"444":2.0,"479":3.0,"485":4.0,"498":1.0,"502":4.0,"504":3.0,"539":4.0,"545":4.0,"558":1.0,"562":3.0,"564":3.0,"599":4.0,"605":5.0,"618":1.0,"622":2.0,"624":4.0,"659":5.0,"665":6.0,"678":1.0,"682":2.0,"684":5.0,"719":6.0,"725":7.0,"738":1.0,"742":2.0,"744":5.0,"779":7.0,"785":8.0,"798":1.0,"802":2.0,"804":6.0,"839":8.0,"845":8.0,"858":1.0,"862":2.0,"864":5.0,"899":8.0,"905":8.0,"918":1.0,"922":2.0,"924":4.0,"959":8.0,"965":8.0,"978":1.0,"982":2.0,"984":4.0,"1019":8.0,"1025":10.0,"1038":1.0,"1042":2.0,"1044":5.0,"1079":10.0,"1085":10.0,"1098":1.0,"1102":2.0,"1104":5.0,"1139":10.0,"1145":11.0,"1158":1.0,"1162":2.0,"1164":5.0,"1199":11.0,"1205":12.0,"1218":1.0,"1222":2.0,"1224":6.0,"1259":12.0,"1265":13.0,"1278":2.0,"1282":1.0,"1284":7.0,"1319":13.0,"1325":13.0,"1338":2.0,"1342":1.0,"1344":6.0,"1379":13.0,"1385":14.0,"1398":2.0,"1402":1.0,"1404":6.0,"1439":14.0,"1445":3.0,"1458":2.0,"1462":1.0,"1464":6.0,"1499":8.0,"1505":3.0,"1518":2.0,"1522":1.0,"1524":6.0,"1559":4.0,"1565":3.0,"1578":2.0,"1582":1.0,"1584":8.0,"1619":5.0}}'
Dataframe:
df_slim = pd.read_json(data)
Chart:
highlight = alt.selection(type='single', on='mouseover',
fields=['Store'], nearest=True, empty="none")
chart = alt.Chart(df_slim).mark_line().encode(
x='Date',
y='Rank',
#color='Store',
strokeDash='Store',
color=alt.condition(highlight, 'Store', alt.value("lightgray")),
tooltip=['Rank','Store']
).properties(
width=800,
height=600,
title='Bump Chart: Store Ranking'
).configure_title(
fontSize=30,
font='Courier',
anchor='start',
color='gray'
).add_selection(
highlight
)
display(chart)
Output:
Any help? Not sure what went wrong here.
Good question! It turns out this is one of the current limitations of Vega-Lite. I found this note in the VL docs on Nearest Value
The nearest transform is not supported for continuous mark types (i.e., line and area). For these mark types, consider layering a discrete mark type (e.g., point) with a 0-value opacity
So for your example I would do something like this
highlight = alt.selection(type='single', on='mouseover',
fields=['Store'], nearest=True, empty="none")
chart = alt.Chart(df_slim).mark_line().encode(
x='Date',
y='Rank',
#color='Store',
strokeDash='Store',
color=alt.condition(highlight, 'Store', alt.value("lightgray")),
tooltip=['Rank','Store']
)
points = alt.Chart(df_slim).mark_point(opacity=0).encode(
x='Date',
y='Rank',).add_selection(
highlight
)
chart + points

Interactive plot selection in Altair does not hi-light points

I am trying to generate 2 plots in Altair that share the same selection.
I would like to plot scatter and bar charts of population (y) vs Age (x). I am using the Altair built-in dataset population. The population is the sum of the people column in this dataset. The dataset has columns for year, people, age and sex. I can get total populate using sum(people) and plot this as y against age. For the bar chart, I can plot similarly sum(people) versus age and color using the sex column.
I am trying to set up a brush/selection between these 2 plots so that I can hilight in the scatter plot and simultaneously the bar plot is updated to reflect that selection. However, I am stuck with the following problem
I am using the layered bar graph example from the Altair documentation for the example.
Here is the code
import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])
df = data.population.url
scatter = alt.Chart(df).mark_point().encode(
alt.X('age:O', axis=alt.Axis(title='')),
y='sum(people)',
color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).transform_filter(
filter = datum.year == 2000
).transform_calculate(
"sex", if_(datum.sex == 2, 'Female', 'Male')
).properties(
selection=interval
)
bar = alt.Chart(df).mark_bar(opacity=0.7).encode(
alt.X('age:O', scale=alt.Scale(rangeStep=17)),
alt.Y('sum(people)', stack=None),
color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).transform_filter(
filter = datum.year == 2000
).transform_calculate(
"sex", if_(datum.sex == 2, 'Female', 'Male')
).properties(height=100, width=400)
scatter & bar
I have modified the code in the documentation example. I am first creating a scatter plot and then using the color based on the selection. Then I define a bar plot of the same 2 columns and again use the selection to specify the color. Here is the output
Now, I would like to drag a box across the top (scatter) plot to select some points and simultaneously the bottom (bar) chart should update based on the selection. When I drag in the top plot to make my selection, this happens
Problems
After dragging to make a selection in the top plot, the colors (inside and outside the selection) in both plots are changed to lightgrey. I expected, in both plots, inside the selection/brush to be hilighted but outside should be lightgrey.
How can I get a selection that is hilighted in both the top and bottom plots simultaneously?
EDIT
I want this behaviour, where a brush/selection in one plot is simultaneously hilighted in a 2nd (linked) plot.
Package versions:
Python = 3.6
Altair = 2.2
Jupyter = 5.6
To trigger a selection on an aggregated value, the best approach is to use an aggregate transform to define that quantity so that it is available to the entire chart.
Here is an example:
import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])
base = alt.Chart(data.population.url).transform_filter(
filter = datum.year == 2000
).transform_calculate(
"sex", if_(datum.sex == 2, 'Female', 'Male')
).transform_aggregate(
population="sum(people)",
groupby=['age', 'sex']
)
scatter = base.mark_point().encode(
alt.X('age:O', title=''),
y='population:Q',
color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).properties(
selection=interval
)
bar = base.mark_bar(opacity=0.7).encode(
alt.X('age:O', scale=alt.Scale(rangeStep=17)),
alt.Y('population:Q'),
color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).properties(height=100, width=400)
scatter & bar
Note that I took away the filtering by the interval selection on the lower plot, because that's not the behavior you described.
Based on (and adapting) the answer by #jakevdp above, I tried something similar to this example from the Interactive Charts section of the docs gallery.
Instead of using a base object, I used the vconcat function, which joins the Chart instances and passes the transform and data to the vconcat object. Here is the approach
import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])
scatter = alt.Chart().mark_point().encode(
alt.X('age:O', title=''),
y='population:Q',
color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).properties(
selection=interval
)
bar = alt.Chart().mark_bar(opacity=0.7).encode(
alt.X('age:O', scale=alt.Scale(rangeStep=17)),
alt.Y('population:Q'),
color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).properties(height=100, width=400)
alt.vconcat(scatter, bar,
data=data.population.url
).transform_filter(
filter = datum.year == 2000
).transform_calculate(
"sex", if_(datum.sex == 2, 'Female', 'Male')
).transform_aggregate(
population="sum(people)",
groupby=['age', 'sex']
)
This approach appears to give the same functionality as #jakevdp's answer.i.e. a selection can be made to the scatter (top) plot and this will be reflected in the bar chart (bottom), as required.

Python - Bokeh vbar hover tool

I have a simple multiple data bar graph (non stacked) and wish to be able to be shown the (max) value of the bar chart upon a hover over with the mouse.
I'm having trouble linking the hover location to the data though. I'm not sure how of the syntax/coding for calling an index from the bar chart.
Here is my code:
from bokeh.io import show, output_file
from bokeh.models import ColumnDataSource, FactorRange
from bokeh.plotting import figure
output_file("bars.html")
LOCATIONS = ['CPC','OG2','HS82-83','IG6','IG4','IG10']
CHECKS = ['AID CHECKS', 'ITEMS SCREENED', 'PERSONS SCREENED']
data = {'LOCATIONS' : LOCATIONS,
'AID CHECKS' : [208,622,140,1842,127,1304],
'PERSONS SCREENED' : [201,484,126,1073,81,676],
'ITEMS SCREENED' : [28,71,31,394,32,207]}
x = [ (location, check) for location in LOCATIONS for check in CHECKS ]
counts = sum(zip(data['AID CHECKS'], data['PERSONS SCREENED'], data['ITEMS SCREENED']), ()) # like an hstack
source = ColumnDataSource(data=dict(x=x, counts=counts))
p = figure(x_range=FactorRange(*x), plot_height=600, plot_width=990, title="NPS Locations by Security Checks",
tools="pan,wheel_zoom,box_zoom,reset, save")
p.xaxis.axis_label_text_font_size = "5pt"
p.xaxis.axis_label_text_font_style='bold'
p.vbar(x='x', top='counts', width=0.9, source=source)
p.add_tools(HoverTool(tooltips=[("LOCATION", "#location"), ("TOTAL", "#check")]))
p.y_range.start = 0
p.x_range.range_padding = 0.1
p.xaxis.major_label_orientation = 1
p.xgrid.grid_line_color = None
show(p)
Adjust the following line:
p.add_tools(HoverTool(tooltips=[("LOCATION", "#x"), ("TOTAL", "#counts")]))
See the documentation:
Field names that begin with # are associated with columns in a
ColumnDataSource. For instance the field name "#price" will display
values from the "price" column whenever a hover is triggered. If the
hover is for the 17th glyph, then the hover tooltip will
correspondingly display the 17th price value.

Categories