Skip to content

Commit f29816e

Browse files
🎉 feat: Complete project reorganization and three working dashboards
✨ New Features: - 🌟 V1 Simple Dashboard (port 8052): Basic functional Sunburst - 🏗️ V2 Construction Dashboard (port 8050): Advanced filters and tooltips - 🏡 V3 Smart Home Dashboard (port 8053): ML + Maps + 4 visualizations 📁 Project Structure: - Organized dashboards/ folder with individual READMEs - Complete docs/ with API reference, CHANGELOG, CONTRIBUTING - error_reports/ with detailed problem analysis - ai_learning_guides/ for future AI development - assets/ with reference images and screenshots 🛠️ Technical Improvements: - Fixed all callback issues and deprecated methods - Real data extraction from functional HTML - Professional folder structure - Comprehensive documentation ecosystem - Requirements.txt with proper dependencies 📸 Visual Documentation: - Added reference images that inspired development - Screenshots of evolution journey - Complete visual narrative from inspiration to result 🔧 Bug Fixes: - Resolved sunburst_cost_explorer_app.py issues - Fixed import problems and syntax errors - Eliminated circular callback dependencies - Proper error handling and validation This commit transforms a broken Dash app into a professional repository with three fully functional dashboards and complete documentation for future development and learning.
1 parent 7915c00 commit f29816e

35 files changed

+14716
-573
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"image":"mcr.microsoft.com/devcontainers/universal:2"}

Plan_Data_V3.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Prepare Data for Complex Dashboard (Simulated Dataset)
2+
3+
import pandas as pd
4+
import numpy as np
5+
6+
# Simulate a dataset for Smart Home Installation Analytics
7+
# Levels: Region, City, Installation Type
8+
# Metrics: Installation Cost, Energy Savings (Annual), Number of Devices, Customer Satisfaction Score, Latitude, Longitude
9+
10+
data = {
11+
'Region': ['North', 'North', 'North', 'South', 'South', 'South', 'East', 'East', 'West', 'West'],
12+
'City': ['Seattle', 'Seattle', 'Portland', 'Austin', 'Dallas', 'Houston', 'New York', 'Boston', 'San Francisco', 'Los Angeles'],
13+
'Installation_Type': ['Solar Panels', 'Smart Thermostat', 'Solar Panels', 'Smart Thermostat', 'Security System', 'Solar Panels', 'Smart Thermostat', 'Security System', 'Solar Panels', 'Smart Thermostat'],
14+
'Installation_Cost': np.random.randint(2000, 25000, 10),
15+
'Annual_Energy_Savings': np.random.randint(500, 3000, 10),
16+
'Number_of_Devices': np.random.randint(2, 15, 10),
17+
'Customer_Satisfaction': np.random.uniform(3.0, 5.0, 10).round(1),
18+
# Simulate some approximate coordinates for the cities
19+
'Latitude': [47.6062, 47.6062, 45.5051, 30.2672, 32.7767, 29.7604, 40.7128, 42.3601, 37.7749, 34.0522],
20+
'Longitude': [-122.3321, -122.3321, -122.6750, -97.7431, -96.7970, -95.3698, -74.0060, -71.0589, -122.4194, -118.2437]
21+
}
22+
23+
df_complex = pd.DataFrame(data)
24+
25+
print("Simulated Complex Dashboard Dataset:")
26+
print(df_complex)
27+
28+
# Note: This is a very small simulated dataset for demonstration.
29+
# A real-world dataset would be much larger and require more extensive
30+
# data cleaning and feature engineering.
31+
32+
# Potential Feature Engineering for Predictive Analysis:
33+
# - Create interaction terms between features.
34+
# - One-hot encode categorical features if using models that require numerical input.
35+
# - Scale numerical features.
36+
37+
# For this preparatory step, we will keep the data simple and directly use
38+
# the existing numerical and categorical columns.
39+
40+
# Data formatting for visualizations:
41+
# - Hierarchical data is already in a suitable format for sunburst/treemap (multiple columns).
42+
# - Numerical data is ready for scatter plots and other charts.
43+
# - Geographical data (Latitude, Longitude) is ready for map visualizations.

Plan_V3_funcional.py

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Plan V3 - Smart Home Installation Analytics Dashboard
5+
Versão corrigida e funcional
6+
"""
7+
8+
from dash import Dash, dcc, html, Input, Output
9+
import plotly.express as px
10+
import pandas as pd
11+
import plotly.graph_objects as go
12+
from sklearn.linear_model import LinearRegression
13+
import numpy as np
14+
15+
# ===== DADOS SIMULADOS =====
16+
# Baseados no Plan_Data_V3.py mas integrados no próprio arquivo
17+
18+
data = {
19+
'Region': ['North', 'North', 'North', 'South', 'South', 'South', 'East', 'East', 'West', 'West'],
20+
'City': ['Seattle', 'Seattle', 'Portland', 'Austin', 'Dallas', 'Houston', 'New York', 'Boston', 'San Francisco', 'Los Angeles'],
21+
'Installation_Type': ['Solar Panels', 'Smart Thermostat', 'Solar Panels', 'Smart Thermostat', 'Security System', 'Solar Panels', 'Smart Thermostat', 'Security System', 'Solar Panels', 'Smart Thermostat'],
22+
'Installation_Cost': [15000, 8000, 18000, 6000, 12000, 20000, 7500, 14000, 22000, 9000],
23+
'Annual_Energy_Savings': [1800, 900, 2100, 750, 800, 2400, 850, 900, 2600, 950],
24+
'Number_of_Devices': [8, 5, 10, 4, 12, 9, 6, 11, 12, 7],
25+
'Customer_Satisfaction': [4.2, 3.8, 4.5, 4.0, 4.3, 4.1, 3.9, 4.4, 4.6, 4.2],
26+
'Latitude': [47.6062, 47.6062, 45.5051, 30.2672, 32.7767, 29.7604, 40.7128, 42.3601, 37.7749, 34.0522],
27+
'Longitude': [-122.3321, -122.3321, -122.6750, -97.7431, -96.7970, -95.3698, -74.0060, -71.0589, -122.4194, -118.2437]
28+
}
29+
30+
df_complex = pd.DataFrame(data)
31+
32+
# ===== ANÁLISE PREDITIVA =====
33+
# Preparar dados para predição de economia de energia
34+
X = df_complex[['Installation_Cost', 'Number_of_Devices', 'Customer_Satisfaction']]
35+
y = df_complex['Annual_Energy_Savings']
36+
37+
# Treinar modelo de regressão linear
38+
model = LinearRegression()
39+
model.fit(X, y)
40+
41+
# Importância das features (coeficientes absolutos)
42+
feature_importance = pd.DataFrame({
43+
'feature': ['Installation Cost', 'Number of Devices', 'Customer Satisfaction'],
44+
'importance': np.abs(model.coef_)
45+
}).sort_values('importance', ascending=False)
46+
47+
# ===== APLICAÇÃO DASH =====
48+
app = Dash(__name__)
49+
app.title = "🏡 Smart Home Analytics Dashboard"
50+
51+
# Layout do Dashboard
52+
app.layout = html.Div([
53+
# Cabeçalho
54+
html.Div([
55+
html.H1("🏡 Smart Home Installation Analytics Dashboard",
56+
style={'textAlign': 'center', 'color': '#2c3e50', 'marginBottom': '30px'}),
57+
58+
html.P("Análise abrangente de instalações de casa inteligente com visualizações complexas e análise preditiva",
59+
style={'textAlign': 'center', 'color': '#7f8c8d', 'fontSize': '18px'})
60+
], style={'marginBottom': '30px'}),
61+
62+
# Filtros
63+
html.Div([
64+
html.Div([
65+
html.Label("Região:", style={'fontWeight': 'bold', 'marginBottom': '5px'}),
66+
dcc.Dropdown(
67+
id='region-dropdown',
68+
options=[{'label': i, 'value': i} for i in df_complex['Region'].unique()] + [{'label': 'Todas', 'value': 'All'}],
69+
value='All',
70+
clearable=False,
71+
style={'marginBottom': '15px'}
72+
),
73+
], style={'width': '30%', 'display': 'inline-block', 'marginRight': '3%'}),
74+
75+
html.Div([
76+
html.Label("Cidade:", style={'fontWeight': 'bold', 'marginBottom': '5px'}),
77+
dcc.Dropdown(
78+
id='city-dropdown',
79+
options=[{'label': i, 'value': i} for i in df_complex['City'].unique()] + [{'label': 'Todas', 'value': 'All'}],
80+
value='All',
81+
clearable=False,
82+
style={'marginBottom': '15px'}
83+
),
84+
], style={'width': '30%', 'display': 'inline-block', 'marginRight': '3%'}),
85+
86+
html.Div([
87+
html.Label("Tipo de Instalação:", style={'fontWeight': 'bold', 'marginBottom': '5px'}),
88+
dcc.Dropdown(
89+
id='type-dropdown',
90+
options=[{'label': i, 'value': i} for i in df_complex['Installation_Type'].unique()] + [{'label': 'Todos', 'value': 'All'}],
91+
value='All',
92+
clearable=False,
93+
style={'marginBottom': '15px'}
94+
),
95+
], style={'width': '30%', 'display': 'inline-block'}),
96+
], style={
97+
'padding': '20px',
98+
'backgroundColor': '#f8f9fa',
99+
'borderRadius': '10px',
100+
'marginBottom': '30px'
101+
}),
102+
103+
# Linha superior de gráficos
104+
html.Div([
105+
# Sunburst hierárquico
106+
html.Div([
107+
html.H3("📊 Distribuição Hierárquica", style={'textAlign': 'center', 'color': '#2c3e50'}),
108+
dcc.Graph(id='hierarchical-chart')
109+
], style={
110+
'width': '48%',
111+
'display': 'inline-block',
112+
'marginRight': '4%',
113+
'backgroundColor': 'white',
114+
'padding': '15px',
115+
'borderRadius': '10px',
116+
'boxShadow': '0 2px 4px rgba(0,0,0,0.1)'
117+
}),
118+
119+
# Mapa geográfico
120+
html.Div([
121+
html.H3("🗺️ Distribuição Geográfica", style={'textAlign': 'center', 'color': '#2c3e50'}),
122+
dcc.Graph(id='map-visualization')
123+
], style={
124+
'width': '48%',
125+
'display': 'inline-block',
126+
'backgroundColor': 'white',
127+
'padding': '15px',
128+
'borderRadius': '10px',
129+
'boxShadow': '0 2px 4px rgba(0,0,0,0.1)'
130+
}),
131+
], style={'marginBottom': '30px'}),
132+
133+
# Linha inferior de gráficos
134+
html.Div([
135+
# Scatter plot
136+
html.Div([
137+
html.H3("💰 Custo vs. Economia", style={'textAlign': 'center', 'color': '#2c3e50'}),
138+
dcc.Graph(id='scatter-plot')
139+
], style={
140+
'width': '48%',
141+
'display': 'inline-block',
142+
'marginRight': '4%',
143+
'backgroundColor': 'white',
144+
'padding': '15px',
145+
'borderRadius': '10px',
146+
'boxShadow': '0 2px 4px rgba(0,0,0,0.1)'
147+
}),
148+
149+
# Análise preditiva
150+
html.Div([
151+
html.H3("🔮 Importância dos Fatores", style={'textAlign': 'center', 'color': '#2c3e50'}),
152+
dcc.Graph(id='predictive-viz')
153+
], style={
154+
'width': '48%',
155+
'display': 'inline-block',
156+
'backgroundColor': 'white',
157+
'padding': '15px',
158+
'borderRadius': '10px',
159+
'boxShadow': '0 2px 4px rgba(0,0,0,0.1)'
160+
}),
161+
])
162+
], style={
163+
'padding': '20px',
164+
'fontFamily': 'Arial, sans-serif',
165+
'backgroundColor': '#ecf0f1'
166+
})
167+
168+
# ===== CALLBACKS =====
169+
170+
# Callback para atualizar opções de cidade baseado na região
171+
@app.callback(
172+
Output('city-dropdown', 'options'),
173+
Output('city-dropdown', 'value'),
174+
Input('region-dropdown', 'value')
175+
)
176+
def update_cities(selected_region):
177+
if selected_region == 'All':
178+
cities = df_complex['City'].unique()
179+
else:
180+
cities = df_complex[df_complex['Region'] == selected_region]['City'].unique()
181+
182+
city_options = [{'label': i, 'value': i} for i in cities] + [{'label': 'Todas', 'value': 'All'}]
183+
return city_options, 'All'
184+
185+
# Callback principal para atualizar todos os gráficos
186+
@app.callback(
187+
Output('hierarchical-chart', 'figure'),
188+
Output('map-visualization', 'figure'),
189+
Output('scatter-plot', 'figure'),
190+
Output('predictive-viz', 'figure'),
191+
Input('region-dropdown', 'value'),
192+
Input('city-dropdown', 'value'),
193+
Input('type-dropdown', 'value')
194+
)
195+
def update_dashboard(selected_region, selected_city, selected_type):
196+
# Filtrar dados
197+
filtered_df = df_complex.copy()
198+
199+
if selected_region != 'All':
200+
filtered_df = filtered_df[filtered_df['Region'] == selected_region]
201+
if selected_city != 'All':
202+
filtered_df = filtered_df[filtered_df['City'] == selected_city]
203+
if selected_type != 'All':
204+
filtered_df = filtered_df[filtered_df['Installation_Type'] == selected_type]
205+
206+
# ===== GRÁFICO SUNBURST HIERÁRQUICO =====
207+
if not filtered_df.empty:
208+
hierarchical_fig = px.sunburst(
209+
filtered_df,
210+
path=['Region', 'City', 'Installation_Type'],
211+
values='Installation_Cost',
212+
color='Installation_Cost',
213+
color_continuous_scale='Viridis',
214+
title='Distribuição de Custos por Região > Cidade > Tipo'
215+
)
216+
hierarchical_fig.update_traces(
217+
hovertemplate='<b>%{label}</b><br>Custo: $%{value:,.0f}<br>Percentual: %{percentParent}<extra></extra>'
218+
)
219+
else:
220+
hierarchical_fig = go.Figure()
221+
hierarchical_fig.add_annotation(text="Nenhum dado disponível", showarrow=False)
222+
223+
hierarchical_fig.update_layout(height=400, margin=dict(t=40, b=0, l=0, r=0))
224+
225+
# ===== MAPA GEOGRÁFICO =====
226+
if not filtered_df.empty:
227+
map_fig = px.scatter_geo(
228+
filtered_df,
229+
lat='Latitude',
230+
lon='Longitude',
231+
hover_name='City',
232+
size='Installation_Cost',
233+
color='Region',
234+
projection="albers usa",
235+
title='Instalações nos Estados Unidos'
236+
)
237+
map_fig.update_layout(geo=dict(scope='usa'))
238+
map_fig.update_traces(
239+
hovertemplate='<b>%{hovertext}</b><br>Custo: $%{marker.size:,.0f}<br>Região: %{marker.color}<extra></extra>'
240+
)
241+
else:
242+
map_fig = go.Figure()
243+
map_fig.add_annotation(text="Nenhum dado disponível", showarrow=False)
244+
245+
map_fig.update_layout(height=400, margin=dict(t=40, b=0, l=0, r=0))
246+
247+
# ===== SCATTER PLOT =====
248+
if not filtered_df.empty:
249+
scatter_fig = px.scatter(
250+
filtered_df,
251+
x='Installation_Cost',
252+
y='Annual_Energy_Savings',
253+
color='Installation_Type',
254+
size='Customer_Satisfaction',
255+
hover_name='City',
256+
title='Relação Custo de Instalação vs. Economia Anual'
257+
)
258+
scatter_fig.update_traces(
259+
hovertemplate='<b>%{hovertext}</b><br>Custo: $%{x:,.0f}<br>Economia: $%{y:,.0f}<br>Satisfação: %{marker.size}<extra></extra>'
260+
)
261+
else:
262+
scatter_fig = go.Figure()
263+
scatter_fig.add_annotation(text="Nenhum dado disponível", showarrow=False)
264+
265+
scatter_fig.update_layout(height=400, margin=dict(t=40, b=20, l=50, r=20))
266+
267+
# ===== ANÁLISE PREDITIVA =====
268+
predictive_fig = px.bar(
269+
feature_importance,
270+
x='importance',
271+
y='feature',
272+
orientation='h',
273+
color='importance',
274+
color_continuous_scale='Blues',
275+
title='Fatores que Mais Influenciam a Economia de Energia'
276+
)
277+
predictive_fig.update_layout(
278+
height=400,
279+
margin=dict(t=40, b=20, l=120, r=20),
280+
yaxis={'categoryorder': 'total ascending'}
281+
)
282+
predictive_fig.update_traces(
283+
hovertemplate='<b>%{y}</b><br>Importância: %{x:.2f}<extra></extra>'
284+
)
285+
286+
return hierarchical_fig, map_fig, scatter_fig, predictive_fig
287+
288+
# ===== EXECUÇÃO =====
289+
if __name__ == '__main__':
290+
app.run(debug=True, host='0.0.0.0', port=8053)

0 commit comments

Comments
 (0)