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
For some reason, the Y-axis while plotting with altair seems to be inverted (would expect values to go from lower (bottom) to higher (top) of the plot). Also, I would like to be able to change the ticks frequency. With older versions I could use ticks=n_ticks but it seems now this argument can take only boolean.
import altair as alt
alt.renderers.enable('notebook')
eff_metals = pd.read_excel(filename, sheet_name='summary_eff_metals')
points = alt.Chart(eff_metals, height=250, width=400).mark_circle().encode(
x=alt.X('Temperature:Q',axis=alt.Axis(title='Temperature (°C)'),
scale=alt.Scale(zero=False, padding=50)),
y=alt.Y('Efficiency:N',axis=alt.Axis(title='Efficiency (%)'),
scale=alt.Scale(zero=False, padding=1)),
color=alt.Color('Element:N'),
)
text = points.mark_text(align='right', dx=0, dy=-5).encode(
text='Element:N'
)
chart = alt.layer(points, text, data=eff_metals,
width=600, height=300)
chart
And the figure:
I don't have your data, so difficult to write working code.
But here's an example of an inverted scale with additional ticks that is similar to the example scatter with tooltips example. See here for it in the vega editor.
import altair as alt
from vega_datasets import data
iris = data.iris()
alt.Chart(iris).mark_point().encode(
x='petalWidth',
y=alt.Y('petalLength', scale=alt.Scale(domain=[7,0]), axis=alt.Axis(tickCount=100)),
color='species'
).interactive()
This might work with your data:
eff_metals = pd.read_excel(filename, sheet_name='summary_eff_metals')
points = alt.Chart(eff_metals, height=250, width=400).mark_circle().encode(
x=alt.X('Temperature:Q',axis=alt.Axis(title='Temperature (°C)'),
scale=alt.Scale(zero=False, padding=50)),
y=alt.Y('Efficiency:N',axis=alt.Axis(title='Efficiency (%)'),
scale=alt.Scale(zero=False, padding=1, domain=[17,1])),
color=alt.Color('Element:N'),
)
text = points.mark_text(align='right', dx=0, dy=-5).encode(
text='Element:N'
)
chart = alt.layer(points, text, data=eff_metals,
width=600, height=300)
chart
However, I think it's possible that you've might just have the wrong type on your efficiency variable. You could try and replace 'Efficiency:N' with `'Efficiency:Q' and that might do it?
While it's possible to reverse the domain manually, that requires hardcoding the bounds.
Instead we can just pass Scale(reverse=True) to the axis encoding, e.g.:
from vega_datasets import data
alt.Chart(data.wheat().head()).mark_bar().encode(
x='wheat:Q',
y=alt.Y('year:O', scale=alt.Scale(reverse=True)),
)
Here it's been passed to alt.Y, so the years are inverted (left) vs the default y='year:O' (right):