Reputation: 3583
I'm trying to plot a vertical line that's dynamically positioned so that when filtering happens, the line will move accordingly. For example, with the below code, I can plot a stationary vertical line at 25K which works with the full dataset as the median, but when the data is filtered to "Americas" only since the x-axis range is now 45K, the line is not at the median position anymore.
So how can I plot a vertical line that's positioned at the x-axis range's median position? Thanks
import pandas as pd
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
df = pd.read_csv('https://raw.githubusercontent.com/yankev/test/master/life-expectancy-per-GDP-2007.csv')
americas = df[(df.continent=='Americas')]
europe = df[(df.continent=='Europe')]
trace_comp0 = go.Scatter(
x=americas.gdp_percap,
y=americas.life_exp,
mode='markers',
marker=dict(size=12,
line=dict(width=1),
color="navy"
),
name='Americas',
text=americas.country,
)
trace_comp1 = go.Scatter(
x=europe.gdp_percap,
y=europe.life_exp,
mode='markers',
marker=dict(size=12,
line=dict(width=1),
color="red"
),
name='Europe',
text=europe.country,
)
data_comp = [trace_comp0, trace_comp1]
layout_comp = go.Layout(
title='Life Expectancy v. Per Capita GDP, 2007',
hovermode='closest',
xaxis=dict(
title='GDP per capita (2000 dollars)',
ticklen=5,
zeroline=False,
gridwidth=2,
range=[0, 50_000],
),
yaxis=dict(
title='Life Expectancy (years)',
ticklen=5,
gridwidth=2,
range=[0, 90],
),
shapes=[
{
'type': 'line',
'x0': 25000,
'y0': 0,
'x1': 25000,
'y1': 85,
'line': {
'color': 'black',
'width': 1
}
}
]
)
fig_comp = go.Figure(data=data_comp, layout=layout_comp)
iplot(fig_comp)
Upvotes: 9
Views: 6127
Reputation: 593
With the help of the @rpanai's answer and using plotly update buttons, the following solution is developed. Check this.
import pandas as pd
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
df = pd.read_csv('https://raw.githubusercontent.com/yankev/test/master/life-expectancy-per-GDP-2007.csv')
americas = df[(df.continent=='Americas')]
europe = df[(df.continent=='Europe')]
# med_eur = europe["gdp_percap"].median()
# med_ame = americas["gdp_percap"].median()
# med_total=pd.DataFrame(list(europe["gdp_percap"])+list(americas["gdp_percap"])).median()[0]
med_eur = europe["gdp_percap"].max()/2
med_ame = americas["gdp_percap"].max()/2
med_total=25000
trace_median0 = go.Scatter(x=[med_total, med_total],
y=[0,85],
mode="lines",
legendgroup="a",
showlegend=False,
marker=dict(size=12,
line=dict(width=0.8),
color="green"
),
name="Median Total"
)
trace_comp1 = go.Scatter(
x=americas.gdp_percap,
y=americas.life_exp,
mode='markers',
marker=dict(size=12,
line=dict(width=1),
color="navy"
),
name='Americas',
text=americas.country
)
trace_median1 = go.Scatter(x=[med_ame, med_ame],
y=[0,90],
mode="lines",
legendgroup="a",
showlegend=False,
marker=dict(size=12,
line=dict(width=0.8),
color="navy"
),
name="Median Americas",
visible=False
)
trace_comp2 = go.Scatter(
x=europe.gdp_percap,
y=europe.life_exp,
mode='markers',
marker=dict(size=12,
line=dict(width=1),
color="red"
),
name='Europe',
text=europe.country,
)
trace_median2 = go.Scatter(x=[med_eur, med_eur],
y=[0,90],
mode="lines",
legendgroup="b",
showlegend=False,
marker=dict(size=12,
line=dict(width=0.8),
color="red"
),
name="Median Europe",
visible=False
)
data_comp = [trace_comp1,trace_median1]+[trace_comp2,trace_median2]+[trace_median0]
layout_comp = go.Layout(
title='Life Expectancy v. Per Capita GDP, 2007',
hovermode='closest',
xaxis=dict(
title='GDP per capita (2000 dollars)',
ticklen=5,
zeroline=False,
gridwidth=2,
range=[0, 50_000],
),
yaxis=dict(
title='Life Expectancy (years)',
ticklen=5,
gridwidth=2,
range=[0, 90],
),
showlegend=False
)
updatemenus = list([
dict(type="buttons",
active=-1,
buttons=list([
dict(label = 'Total Dataset ',
method = 'update',
args = [{'visible': [True,False,True,False,True]},
{'title': 'Life Expectancy v. Per Capita GDP, 2007'}]),
dict(label = 'Americas',
method = 'update',
args = [{'visible': [True,True, False, False,False]},
{'title': 'Americas'}]),
dict(label = 'Europe',
method = 'update',
args = [{'visible': [False, False,True,True,False]},
{'title': 'Europe'}])
]),
)
])
annotations = list([
dict(text='Trace type:', x=0, y=1.085, yref='paper', align='left', showarrow=False)
])
layout_comp['updatemenus'] = updatemenus
layout_comp['annotations'] = annotations
fig_comp = go.Figure(data=data_comp, layout=layout_comp)
iplot(fig_comp)
Upvotes: 7
Reputation: 13437
This is not quite exactly what you asked. As I doubt you can achieve to show the median of visible traces only without dash
as correctly pointed out by Mike_H. Anyway it could be useful if you want to use a plotly
only solution. So if you are happy with this outputs
You can use the following code. Where the main differences is that we use traces for vertical lines instead of shapes and we play with legendgroup
and showlegend
parameters
import pandas as pd
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
df = pd.read_csv('https://raw.githubusercontent.com/yankev/test/master/life-expectancy-per-GDP-2007.csv')
americas = df[(df.continent=='Americas')]
europe = df[(df.continent=='Europe')]
med_eur = europe["gdp_percap"].median()
med_ame = americas["gdp_percap"].median()
trace_comp0 = go.Scatter(
x=americas.gdp_percap,
y=americas.life_exp,
mode='markers',
marker=dict(size=12,
line=dict(width=1),
color="navy"
),
name='Americas',
text=americas.country,
legendgroup="a",
)
trace_median0 = go.Scatter(x=[med_ame, med_ame],
y=[0,90],
mode="lines",
legendgroup="a",
showlegend=False,
marker=dict(size=12,
line=dict(width=0.8),
color="navy"
),
name="Median Americas",
)
trace_comp1 = go.Scatter(
x=europe.gdp_percap,
y=europe.life_exp,
mode='markers',
marker=dict(size=12,
line=dict(width=1),
color="red"
),
name='Europe',
text=europe.country,
legendgroup="b",
)
trace_median1 = go.Scatter(x=[med_eur, med_eur],
y=[0,90],
mode="lines",
legendgroup="b",
showlegend=False,
marker=dict(size=12,
line=dict(width=0.8),
color="red"
),
name="Median Europe",
)
data_comp = [trace_comp0, trace_median0,
trace_comp1, trace_median1]
layout_comp = go.Layout(
title='Life Expectancy v. Per Capita GDP, 2007',
hovermode='closest',
xaxis=dict(
title='GDP per capita (2000 dollars)',
ticklen=5,
zeroline=False,
gridwidth=2,
range=[0, 50_000],
),
yaxis=dict(
title='Life Expectancy (years)',
ticklen=5,
gridwidth=2,
range=[0, 90],
),
)
fig_comp = go.Figure(data=data_comp, layout=layout_comp)
iplot(fig_comp)
Upvotes: 1