I have figured out a solution on how to use multiple filters. I believe it is straightforward but for a newbie like me it was quite hard to come up with it. So I thought I share it in case somebody else comes along:
In the front end I have a download button:
import os
import pandas as pd
import io
import flask
import dash
import dash_core_components as dcc
import dash_html_components as html
from datetime import datetime as dt
app = dash.Dash()
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'})
app.layout = html.Div([
html.A(html.Button('Download', id='download-button'), id='download-link')])
Note that you will need to add your dcc components above to filter the dataframe (in my case: gender-picker, joindate and state-picker). The way I do it from here is to merge all my filters on the dataframe in the link like this:
@app.callback(
dash.dependencies.Output('download-link', 'href'),
[dash.dependencies.Input('gender-picker', 'values'),
dash.dependencies.Input('joindate', 'start_date'),
dash.dependencies.Input('state-picker', 'values')])
def update_link(selected_gender, join_start_date, join_end_date, selected_state):
return '/dash/urlToDownload?value={}/{}/{}'.format('-'.join(selected_gender),
dt.strptime(join_start_date,'%Y-%M-%d'),
'-'.join(selected_state))
Then I get the value and decompose it in its single parts which I then use to subset my dataframe:
@app.server.route('/dash/urlToDownload')
def download_csv():
value = flask.request.args.get('value')
#here is where I split the value
value = value.split('/')
selected_gender = value[0].split('-')
selected_state = value[2].split('-')
join_start_date = value[1]
filtered_df = df[df['Gender'].isin(selected_gender)]
filtered_df = filtered_df[filtered_df['zip_state'].isin(selected_state)]
filtered_df = filtered_df.loc[(demographics['JoinDate'] >= join_start_date),]
#if you use Python 3, use io.StringIO()
str_io = io.BytesIO()
filtered_df.to_csv(str_io)
mem = io.BytesIO()
mem.write(str_io.getvalue().encode('utf-8'))
mem.seek(0)
str_io.close()
return flask.send_file(mem,
mimetype='text/csv',
attachment_filename='downloadFile.csv',
as_attachment=True)
if __name__ == '__main__':
app.run_server()