Skip to content

Instantly share code, notes, and snippets.

@gschivley
Created May 13, 2018 18:32
Show Gist options
  • Save gschivley/578c344461100071b7eef158efccce95 to your computer and use it in GitHub Desktop.
Save gschivley/578c344461100071b7eef158efccce95 to your computer and use it in GitHub Desktop.
Altair plot in Plotly Dash
# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import sqlalchemy
import altair as alt
import io
from vega_datasets import data
# Don't need this with the cars dataset
alt.data_transformers.enable('default', max_rows=10000)
# Not using sql here
# conn = sqlalchemy.create_engine()
cars = data.cars()
app = dash.Dash(__name__, static_folder='assets')
app.css.append_css({'external_url':
'https://cdn.rawgit.com/gschivley/8040fc3c7e11d2a4e7f0589ffc829a02/raw/fe763af6be3fc79eca341b04cd641124de6f6f0d/dash.css'
})
app.title = 'Test dash and altair'
server = app.server
app.layout = html.Div([
html.Div([
html.P([
html.Label('x-axis'),
# dcc.Input(id='mother_birth', value=1952, type='number'),
dcc.Dropdown(
id='x_axis',
options=[{'label': i, 'value':i} for i in cars.columns],
value='Acceleration'
)
],
style={'width': '250px', 'margin-right': 'auto',
'margin-left': 'auto', 'text-align': 'center'}),
html.P([
html.Label('y-axis'),
# dcc.Input(id='mother_birth', value=1952, type='number'),
dcc.Dropdown(
id='y_axis',
options=[{'label': i, 'value':i} for i in cars.columns],
value='Miles_per_Gallon'
)
],
style={'width': '250px', 'margin-right': 'auto',
'margin-left': 'auto', 'text-align': 'center'})],
className='input-wrapper'),
html.Iframe(
id='plot',
height='500',
width='1000',
sandbox='allow-scripts',
# This is where we will pass the html
# srcDoc=
# Get rid of the border box
style={'border-width': '0px'}
)
])
@app.callback(
dash.dependencies.Output('plot', 'srcDoc'),
[dash.dependencies.Input('x_axis', 'value'),
dash.dependencies.Input('y_axis', 'value')]
)
def pick_figure(x_axis, y_axis):
brush = alt.selection_interval()
points_cars = alt.Chart(cars).mark_point().encode(
x=x_axis,
y=y_axis,
).properties(
width=250,
height=250,
selection=brush
)
bars = alt.Chart(cars).mark_bar().encode(
x='Horsepower:Q',
y='count()'
).transform_filter(
brush.ref()
)
chart = alt.hconcat(points_cars, bars)
# Save html as a StringIO object in memory
cars_html = io.StringIO()
chart.save(cars_html, 'html')
# Return the html from StringIO object
return cars_html.getvalue()
if __name__ == '__main__':
app.run_server(debug=True)
@MarshallCharles
Copy link

This is nice, but altair plots render very slowly in browser using this method. Have you found a way around this at all? For example, when using local data in a pandas dataframe as opposed to a vega dataset.

@firasm
Copy link

firasm commented Jul 11, 2019

Thanks for this, this is great!

one only needs to make one small change to make this compatible with Dash 1.0.1 and that is in line 20, "static_folder" needs to change to "assets_folder".

Much appreciated!

@yonglid
Copy link

yonglid commented Mar 10, 2020

Had a lot of trouble getting this running because string values being passed into srcDoc were causing vega issues from Altair but the html works just fine. So used src attribute and opened the html (not string version to html! but just straight to html file itself) and it worked.

@damajojung
Copy link

Many thanks, helped me a lot with my project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment