Remove legend for points in Altair - python

I'm following this example https://altair-viz.github.io/gallery/multiline_highlight.html, and added text points. My lines have both strokeDash and color.
import altair as alt
from vega_datasets import data
source = data.stocks()
highlight = alt.selection(type='single', on='mouseover',
fields=['symbol'], nearest=True)
base = alt.Chart(source).encode(
x='date:T',
y='price:Q',
color='symbol:N',
strokeDash='symbol:N'
)
points = base.mark_circle().encode(
opacity=alt.value(0)
).add_selection(
highlight
).properties(
width=600
)
lines = base.mark_line().encode(
size=alt.condition(~highlight, alt.value(1), alt.value(3))
)
points + lines
I'd like the legend to only show the dashed and colored lines, not the others (legend for text and points iiuc)
Is it possible to completely remove the extra legends from a chart?

It is enough to explicitly remove the legend on points and text by setting the color and strokeDash attributes
import altair as alt
from vega_datasets import data
source = data.stocks()
highlight = alt.selection(type='single', on='mouseover',
fields=['symbol'], nearest=True)
base = alt.Chart(source).encode(
x='date:T',
y='price:Q',
color='symbol:N',
strokeDash='symbol:N'
)
points = base.mark_point().encode(
opacity=alt.value(0),
color=alt.Color('symbol:N', legend=None),
strokeDash=alt.StrokeDash('symbol:N', legend=None)
).add_selection(
highlight
).properties(
width=600
)
lines = base.mark_line().encode(
size=alt.condition(~highlight, alt.value(1), alt.value(3))
)
text = lines.mark_text(
align='left',
baseline='middle',
dx=7
).encode(
text='symbol',
color=alt.Color('symbol:N', legend=None),
strokeDash=alt.StrokeDash('symbol:N', legend=None)
)
(lines + points + text).resolve_scale(color='independent', strokeDash='independent')

Related

how to add annotation of last value in stacked area chart?

I created a stacked area chart using stackgroup= and now I'd like to add annotation to last value.
I am copying the code from here and made some modification.
Plotly: How to annotate end of multiple lines with text and marker colors that match the lines?
this is the original plot for stacked area chart
for ipad,pad in enumerate(pad_list):
for iwell,well in enumerate(cols_thispad):
fig.add_scatter(
x=df.index,
y=df[well].values,
mode='lines',
line={"color": colors_discrete[iwell]}, #"color": "#035593"
stackgroup=str(ipad+1), # define stack group
name=well,
row=ipad+1,
col=1,
legendgroup = str(ipad+1),
meta=well,
text=[key.title()+unit_thiskey]*len(df.index),
hovertemplate='%{meta}<br>Datetime: %{x}<br>%{text}:%{y}<extra></extra>',
)
after plotting, I'd like to add annotation to last value of each stacked area chat, here is what I did, if I use stackgroup=, the plot is completely wrong. If I remove stackgroup= in below chat, the last values can be shown and in right chart. However, it is not stacked. so how to show last value markers in stack mode? Thanks
for i, d in enumerate(fig.data):
padname=d.name.split('A')[1][:2]
padname_ix=pad_list.index(padname)
legendgroup=str(padname_ix+1)
row=padname_ix+1
stackgroup=str(padname_ix+1)
fig.add_scatter(x=[d.x[-1]], y = [d.y[-1]],
mode = 'markers+text',
text = f'{d.y[-1]:.2f}',
textfont = dict(color=d.line.color),
textposition='middle right',
marker = dict(color = d.line.color, size = 12),
legendgroup = legendgroup, #d.name,\
stackgroup=stackgroup,
row=row,col=1,
showlegend=False)
here is the plot without using stackgroup in the 2nd code. It works but not correctly.
Since this function groups stacked graphs, the issue can be resolved by giving each group unit a unique name. In the example answer, the area graph is named 'one' and the text annotation by scatter is named 'two'.
import yfinance as yf
ticker = ['AAPL','GOOGL','TSLA','MSFT']
data = yf.download(ticker, start="2021-01-01", end="2021-03-01")['Close']
import plotly.graph_objects as go
fig = go.Figure()
for t in data.columns:
fig.add_trace(go.Scatter(x=data.index,
y=data[t],
hoverinfo='x+y',
mode='lines',
stackgroup='one',
name=t
)
)
fig.add_trace(go.Scatter(x=[data.index[-1]],
y=[data[t][-1]],
mode='markers+text',
text=round(data[t][-1],2),
textposition='middle left',
stackgroup='two',
name=t,
showlegend=False
)
)
fig.update_layout(height=600
)
fig.show()

Parallel coordinates in Altair

I want to do a parallel coordinates plot with multiple y axis. I've found how to do it in Vega-Lite here but I haven't found the way to do it with Altair, there's only a very simple example where all the y axis are the same.
Is there any way to do this plot in altair?
Note that this kind of chart is not "built-in" to Altair or Vega-Lite, so the only way to create it is with a manual sequence of transforms, and manually constructing your axes from tick and text marks.
Here is an Altair version of the chart in the answer you linked to:
import altair as alt
from vega_datasets import data
base = alt.Chart(
data.iris.url
).transform_window(
index="count()"
).transform_fold(
["petalLength", "petalWidth", "sepalLength", "sepalWidth"]
).transform_joinaggregate(
min="min(value)",
max="max(value)",
groupby=["key"]
).transform_calculate(
norm_val="(datum.value - datum.min) / (datum.max - datum.min)",
mid="(datum.min + datum.max) / 2"
).properties(width=600, height=300)
lines = base.mark_line(opacity=0.3).encode(
x='key:N',
y=alt.Y('norm_val:Q', axis=None),
color="species:N",
detail="index:N",
tooltip=["petalLength:N", "petalWidth:N", "sepalLength:N", "sepalWidth:N"]
)
rules = base.mark_rule(
color="#ccc", tooltip=None
).encode(
x="key:N",
detail="count():Q",
)
def ytick(yvalue, field):
scale = base.encode(x='key:N', y=alt.value(yvalue), text=f"min({field}):Q")
return alt.layer(
scale.mark_text(baseline="middle", align="right", dx=-5, tooltip=None),
scale.mark_tick(size=8, color="#ccc", orient="horizontal", tooltip=None)
)
alt.layer(
lines, rules, ytick(0, "max"), ytick(150, "mid"), ytick(300, "min")
).configure_axisX(
domain=False, labelAngle=0, tickColor="#ccc", title=None
).configure_view(
stroke=None
)

How to apply borders around each y axis label for Altair in Python

I have a visualization I made in Altair and I want to place borders around each label on the y axis (sorry if I am explaining this incorrectly) to separate them. This is the code I have so far:
alt.Chart(q4df).transform_fold(
rosspaints,
as_=['column', 'value']
).mark_circle().encode(
x = alt.X('column:N', axis=None),
y = alt.Y('TITLE', title=None),
size = alt.Size('value:Q', legend=None),
color=alt.Color('column:N', legend=None,
scale=alt.Scale(
domain=['alizarin crimson','bright red','burnt umber','cadmium yellow','dark sienna',
'indian yellow','indian red','liquid black','liquid clear','black gesso',
'midnight black','phthalo blue','phthalo green','prussian blue','sap green',
'titanium white','van dyke brown','yellow ochre'],
range=['#94261f','#c06341','#614f4b','#f8ed57','#5c2f08','#e6ba25','#cd5c5c',
'#000000','#ffffff','#000000','#36373c','#2a64ad','#215c2c','#325fa3',
'#364e00','#f9f7eb','#2d1a0c','#b28426']))
).properties(
width=400,
height=700
).configure_axis(grid=False, labelFontWeight= 'bold', labelColor='black')
This is my current output:
This is my desired output:
You could either set a gridline for each y-axis tick like this:
import altair as alt
from vega_datasets import data
source = data.barley()
alt.Chart(source).mark_point().encode(
alt.X('yield:Q', axis=alt.Axis(grid=False)),
alt.Y('variety:N', axis=alt.Axis(grid=True)),
color='year:N'
).configure_view(
stroke=None
)
Or use facet according to the same variable you have encoded on the y-axis while resolving the y-scale so that only the y-axis entry with data points shows up in each plot:
alt.Chart(source).mark_point().encode(
alt.X('yield:Q', axis=alt.Axis(grid=False)),
alt.Y('variety:N', title=''),
color='year:N',
).facet(
row=alt.Facet('variety:N', title='', header=alt.Header(labels=False))
).resolve_scale(
y='independent'
)

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

Retain tooltip of previous layer in Altair

I am adding states outline overlay on my choropleth plot in altair
My choropleth plot has tooltip for it.
When I layer the state outline on top of the choropleth I lose the tooltip feature of the plot
Anyone have ideas on how to handle this?
Any help would be appreciated
import altair as alt
# saving data into a file rather than embedding into the chart
alt.data_transformers.enable('json')
alt.renderers.enable('notebook')
# alt.renderers.enable('jupyterlab')
from vega_datasets import data
import pandas as pd
from altair import Scale,Color
states = alt.topo_feature(data.us_10m.url, 'states')
counties = alt.topo_feature(data.us_10m.url+'#', 'counties')
dummy='#dbe9f6'
scheme='blues'
type1='linear'
fg = alt.Chart(counties).mark_geoshape(
stroke='black',
strokeWidth=0.05
).project(
type='albersUsa'
).transform_lookup(
lookup='id',
from_=alt.LookupData(fdf, 'fips', ['year','Pill_per_pop','BUYER_COUNTY', 'state'])
).transform_calculate(
Pill_per_pop='isValid(datum.Pill_per_pop) ? datum.Pill_per_pop : -1'
).encode(
color = alt.condition(
'datum.Pill_per_pop > 0',
alt.Color('Pill_per_pop:Q', scale=Scale(scheme=scheme,type=type1)),
alt.value(dummy)
),
tooltip=['BUYER_COUNTY:N', 'state:N','Pill_per_pop:Q','year:Q']
).properties(
width=700,
height=400,
title='Pills per 100k people'
)
outline = alt.Chart(states).mark_geoshape(stroke='black',strokeWidth=0.2).project(
type='albersUsa'
)
fg+outline
My output
However I am unable to find a way to retain the tooltip of the previous layer i.e. county level map
I figured it out
Define a new chart as follows:
fg1 = alt.Chart(counties).mark_geoshape(
stroke='black',
strokeWidth=0.05
).project(
type='albersUsa'
).transform_lookup(
lookup='id',
from_=alt.LookupData(fdf, 'fips', ['year','Pill_per_pop','BUYER_COUNTY', 'state'])
).transform_calculate(
Pill_per_pop='isValid(datum.Pill_per_pop) ? datum.Pill_per_pop : -1'
).encode(
tooltip=['BUYER_COUNTY:N', 'state:N','Pill_per_pop:Q','year:Q']
).properties(
width=700,
height=400,
title='Pills per 100k people'
)
fg+outline+fg1
Just define the chart again with encoding for tool-tip and not for color and layer it on top of the above chart.

Categories