{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Vamos agora falar de interação 🕹️\n",
"\n",
"fonte e material de apoio : https://www.kaggle.com/discussions/getting-started/100831\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Os recursos de visualização podem ser muito bem aproveitados se inserirmos recursos onde o usuário pode interagir com nossa visualização 📊\n",
"\n",
"### Para isso temos, algumas opções : ipywidgets, D3.js, Bokeh, Plotly , Dash."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_44521/2402724060.py:2: UserWarning: \n",
"The dash_core_components package is deprecated. Please replace\n",
"`import dash_core_components as dcc` with `from dash import dcc`\n",
" import dash_core_components as dcc\n",
"/tmp/ipykernel_44521/2402724060.py:3: UserWarning: \n",
"The dash_html_components package is deprecated. Please replace\n",
"`import dash_html_components as html` with `from dash import html`\n",
" import dash_html_components as html\n"
]
}
],
"source": [
"import dash\n",
"import dash_core_components as dcc\n",
"import dash_html_components as html\n",
"import plotly.graph_objs as go\n",
"import pandas as pd\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_excel(\"https://github.com/chris1610/pbpython/blob/master/data/salesfunnel.xlsx?raw=True\")\n",
"pv = pd.pivot_table(df, index=['Name'], columns=[\"Status\"], values=['Quantity'], aggfunc=sum, fill_value=0)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"trace1 = go.Bar(x=pv.index, y=pv[('Quantity', 'declined')], name='Declined')\n",
"trace2 = go.Bar(x=pv.index, y=pv[('Quantity', 'pending')], name='Pending')\n",
"trace3 = go.Bar(x=pv.index, y=pv[('Quantity', 'presented')], name='Presented')\n",
"trace4 = go.Bar(x=pv.index, y=pv[('Quantity', 'won')], name='Won')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Primeiro vamos ao layout\n",
"### Para fazer isso utilizaremos componentes HTML que já conhecemos, como H1, Divs, Tabs, "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"app1 = dash.Dash()\n",
"\n",
"app1.layout = html.Div([\n",
" html.H1('Sales Funnel Report'),\n",
" html.Div('National Sales Funnel Report.'),\n",
" dcc.Graph(\n",
" id='example-graph',\n",
" figure={\n",
" 'data': [trace1, trace2, trace3, trace4],\n",
" 'layout':\n",
" go.Layout(title='Order Status by Customer', barmode='stack')\n",
" })\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"app1.run_server(debug=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vamos agora criar uma interação, colocando a opção para o usuário inserir o 'Manager' que ele quer visualizar.\n",
"## Faremos isso com um dropdown\n",
"## Nele, colocaremos as opções de 'managers' que o usuário poderá selecionar"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import dash\n",
"import dash_core_components as dcc\n",
"import dash_html_components as html\n",
"import plotly.graph_objs as go\n",
"import pandas as pd\n",
"\n",
"df = pd.read_excel(\n",
" \"https://github.com/chris1610/pbpython/blob/master/data/salesfunnel.xlsx?raw=True\"\n",
")\n",
"mgr_options = list(df[\"Manager\"].unique())\n",
"\n",
"\n",
"\n",
"mgr_options.append('All Managers')\n",
"\n",
"app = dash.Dash()\n",
"\n",
"app.layout = html.Div([\n",
" html.H2(\"Sales Funnel Report\"),\n",
" html.Div( # Criaremos outra div\n",
" [ \n",
" dcc.Dropdown( # E dentro dela um dropdown\n",
" id=\"Manager\",\n",
" options=[{\n",
" 'label': i,\n",
" 'value': i\n",
" } for i in mgr_options],\n",
" value='All Managers'),\n",
" ],\n",
" style={'width': '25%', # podemos adicionar CSS desta forma\n",
" 'display': 'inline-block'}),\n",
" dcc.Graph(id='funnel-graph'),\n",
"])\n",
"\n",
"\n",
"@app.callback(\n",
" dash.dependencies.Output('funnel-graph', 'figure'),\n",
" [dash.dependencies.Input('Manager', 'value')])\n",
"def update_graph(Manager):\n",
" if Manager == \"All Managers\":\n",
" df_plot = df.copy()\n",
" else:\n",
" df_plot = df[df['Manager'] == Manager]\n",
"\n",
" pv = pd.pivot_table(\n",
" df_plot,\n",
" index=['Name'],\n",
" columns=[\"Status\"],\n",
" values=['Quantity'],\n",
" aggfunc=sum,\n",
" fill_value=0)\n",
"\n",
" trace1 = go.Bar(x=pv.index, y=pv[('Quantity', 'declined')], name='Declined')\n",
" trace2 = go.Bar(x=pv.index, y=pv[('Quantity', 'pending')], name='Pending')\n",
" trace3 = go.Bar(x=pv.index, y=pv[('Quantity', 'presented')], name='Presented')\n",
" trace4 = go.Bar(x=pv.index, y=pv[('Quantity', 'won')], name='Won')\n",
"\n",
" return {\n",
" 'data': [trace1, trace2, trace3, trace4],\n",
" 'layout':\n",
" go.Layout(\n",
" title='Customer Order Status for {}'.format(Manager),\n",
" barmode='stack')\n",
" }\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" app.run_server(debug=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Muito interessante as possibilidades correto? Vamos entender um pouco do funcionamento básico dessa biblioteca"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A primeira parte é sobre o layout e depois falaremos sobre as callbacks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Temos abaixo um código simples de um dataset sobre expectativa de vida no mundo."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Run this app with `python app.py` and\n",
"# visit http://127.0.0.1:8050/ in your web browser.\n",
"\n",
"\n",
"from dash import Dash, dcc, html\n",
"import plotly.express as px\n",
"import pandas as pd\n",
"\n",
"\n",
"app = Dash(__name__)\n",
"\n",
"df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/5d1ea79569ed194d432e56108a04d188/raw/a9f9e8076b837d541398e999dcbac2b2826a81f8/gdp-life-exp-2007.csv')\n",
"\n",
"fig = px.scatter(df, x=\"gdp per capita\", y=\"life expectancy\",\n",
" size=\"population\", color=\"continent\", hover_name=\"country\",\n",
" log_x=True, size_max=60)\n",
"\n",
"app.layout = html.Div([\n",
" dcc.Graph(\n",
" id='life-exp-vs-gdp',\n",
" figure=fig\n",
" )\n",
"])\n",
"\n",
"if __name__ == '__main__':\n",
" app.run(debug=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Porém ele está muito simples, vamos colocar mais plots nele.."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from dash import Dash, dcc, html\n",
"import plotly.express as px\n",
"import pandas as pd\n",
"\n",
"app = Dash(__name__)\n",
"\n",
"# Carregue os dados do DataFrame\n",
"df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/5d1ea79569ed194d432e56108a04d188/raw/a9f9e8076b837d541398e999dcbac2b2826a81f8/gdp-life-exp-2007.csv')\n",
"\n",
"# Crie a primeira visualização de gráfico (gráfico de dispersão)\n",
"fig = px.scatter(df, x=\"gdp per capita\", y=\"life expectancy\",\n",
" size=\"population\", color=\"continent\", hover_name=\"country\",\n",
" log_x=True, size_max=60)\n",
"\n",
"# Crie uma segunda visualização de gráfico (por exemplo, um gráfico de barras)\n",
"# Substitua os dados e a configuração de gráfico apropriados para a segunda visualização\n",
"fig2 = px.bar(df, x=\"country\", y=\"gdp per capita\")\n",
"\n",
"app.layout = html.Div([\n",
" dcc.Graph(\n",
" id='life-exp-vs-gdp',\n",
" figure=fig\n",
" ),\n",
" dcc.Graph(\n",
" id='gdp-per-capita-bar',\n",
" figure=fig2 # Use a segunda visualização de gráfico aqui\n",
" )\n",
"])\n",
"\n",
"if __name__ == '__main__':\n",
" app.run_server(debug=True)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Que tal deixar ele mais bonito e organizado? CSS nele."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from dash import Dash, dcc, html\n",
"import plotly.express as px\n",
"import pandas as pd\n",
"\n",
"app = Dash(__name__)\n",
"\n",
"# Load the data into a DataFrame\n",
"df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/5d1ea79569ed194d432e56108a04d188/raw/a9f9e8076b837d541398e999dcbac2b2826a81f8/gdp-life-exp-2007.csv')\n",
"\n",
"# Create the first visualization (scatter plot)\n",
"fig = px.scatter(df, x=\"gdp per capita\", y=\"life expectancy\",\n",
" size=\"population\", color=\"continent\", hover_name=\"country\",\n",
" log_x=True, size_max=60)\n",
"\n",
"# Create the second visualization (bar chart)\n",
"fig2 = px.bar(df, x=\"country\", y=\"gdp per capita\")\n",
"\n",
"app.layout = html.Div([\n",
" html.Div([\n",
" html.H3(\"Scatter Plot: Life Expectancy vs. GDP Per Capita\"),\n",
" dcc.Graph(\n",
" id='life-exp-vs-gdp',\n",
" figure=fig\n",
" ),\n",
" ], style={'width': '49%', 'display': 'inline-block'}),\n",
" \n",
" html.Div([\n",
" html.H3(\"Bar Chart: GDP Per Capita by Country\"),\n",
" dcc.Graph(\n",
" id='gdp-per-capita-bar',\n",
" figure=fig2\n",
" ),\n",
" ], style={'width': '49%', 'display': 'inline-block'})\n",
"])\n",
"\n",
"if __name__ == '__main__':\n",
" app.run_server(debug=True)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## E agora funções de interação de dados."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mO Kernel falhou ao executar o código na célula atual ou em uma célula anterior. Examine o código nas células para identificar uma possível causa da falha. Clique aqui para obter mais informações. Consulte o log do Jupyter para obter mais detalhes."
]
}
],
"source": [
"from dash import Dash, dcc, html, Input, Output\n",
"import plotly.express as px\n",
"import pandas as pd\n",
"\n",
"app = Dash(__name__)\n",
"\n",
"# Load the data into a DataFrame\n",
"df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/5d1ea79569ed194d432e56108a04d188/raw/a9f9e8076b837d541398e999dcbac2b2826a81f8/gdp-life-exp-2007.csv')\n",
"\n",
"# Create the first visualization (scatter plot)\n",
"fig = px.scatter(df, x=\"gdp per capita\", y=\"life expectancy\",\n",
" size=\"population\", color=\"continent\", hover_name=\"country\",\n",
" size_max=60)\n",
"\n",
"# Create the second visualization (bar chart)\n",
"fig2 = px.bar(df, x=\"country\", y=\"gdp per capita\")\n",
"\n",
"app.layout = html.Div([\n",
" html.Div([\n",
" html.H3(\"Scatter Plot: Life Expectancy vs. GDP Per Capita\"),\n",
" dcc.RadioItems(\n",
" id='log-scale',\n",
" options=[\n",
" {'label': 'Log Scale', 'value': 'log'},\n",
" {'label': 'Linear Scale', 'value': 'linear'}\n",
" ],\n",
" value='log',\n",
" labelStyle={'display': 'block'}\n",
" ),\n",
" dcc.Graph(\n",
" id='life-exp-vs-gdp',\n",
" figure=fig\n",
" )\n",
" ], style={'width': '49%', 'display': 'inline-block'}),\n",
" \n",
" html.Div([\n",
" html.H3(\"Bar Chart: GDP Per Capita by Country\"),\n",
" dcc.Graph(\n",
" id='gdp-per-capita-bar',\n",
" figure=fig2\n",
" ),\n",
" dcc.Slider(\n",
" id='country-count-slider',\n",
" min=10,\n",
" max=len(df),\n",
" step=10,\n",
" value=len(df),\n",
" marks={i: {'label': str(i), 'style': {'transform': 'rotate(-45deg)'}} for i in range(10, len(df) + 1, 10)},\n",
" ),\n",
" dcc.Dropdown(\n",
" id='sorting-dropdown',\n",
" options=[\n",
" {'label': 'Sort by Alphabetical Order', 'value': 'alphabetical'},\n",
" {'label': 'Sort by GDP per Capita', 'value': 'gdp'},\n",
" ],\n",
" value='alphabetical',\n",
" style={'width': '50%'}\n",
" )\n",
" ], style={'width': '49%', 'display': 'inline-block'})\n",
"])\n",
"\n",
"@app.callback(\n",
" Output('gdp-per-capita-bar', 'figure'),\n",
" Input('country-count-slider', 'value'),\n",
" Input('sorting-dropdown', 'value')\n",
")\n",
"def update_country_count(selected_count, sorting_option):\n",
" if sorting_option == 'alphabetical':\n",
" sorted_df = df.sort_values(by='country').head(selected_count)\n",
" else:\n",
" sorted_df = df.sort_values(by='gdp per capita', ascending=False).head(selected_count)\n",
" \n",
" updated_fig = px.bar(sorted_df, x=\"country\", y=\"gdp per capita\")\n",
" return updated_fig\n",
"\n",
"@app.callback(\n",
" Output('life-exp-vs-gdp', 'figure'),\n",
" Input('log-scale', 'value')\n",
")\n",
"def update_scale(selected_scale):\n",
" updated_fig = px.scatter(df, x=\"gdp per capita\", y=\"life expectancy\",\n",
" size=\"population\", color=\"continent\", hover_name=\"country\",\n",
" size_max=60, log_x=(selected_scale == 'log'))\n",
" return updated_fig\n",
"\n",
"if __name__ == '__main__':\n",
" app.run_server(debug=True)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}