GianJSX commited on
Commit
e205fbc
1 Parent(s): c1af6a4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +252 -242
app.py CHANGED
@@ -1,242 +1,252 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import matplotlib.pyplot as plt
4
-
5
- st.image("images/ledesma-logo.png")
6
- st.title('Demo monitoreo de precios')
7
- st.divider()
8
-
9
- st.subheader("Sucursales:")
10
- st.write("Seleccionamos arbitrariamente algunas regiones del pais, e incluimos algunas cadenas de supermercados en cada una de ellas")
11
-
12
- df = pd.read_csv("products.csv")
13
- df_historic = pd.read_csv("historico_precios.csv")
14
-
15
- product_stores = pd.read_csv("Store-Products.csv")
16
- stores = pd.read_csv("sucursales.csv")
17
- provinces = stores['provincia'].unique()
18
- provinces_dict = {
19
- 'Ciudad Autónoma de Buenos Aires': 'AR-C',
20
- 'La Rioja': 'AR-F',
21
- 'Santiago del Estero': 'AR-G',
22
- 'Catamarca': 'AR-K',
23
- 'Neuquén': 'AR-Q',
24
- 'Río Negro': 'AR-R',
25
- 'Santa Fe': 'AR-S',
26
- 'Tucumán': 'AR-T',
27
- 'Chubut': 'AR-U',
28
- 'Córdoba': 'AR-X',
29
- 'Santa Cruz': 'AR-Z'
30
- }
31
-
32
- provinces_dataframe = pd.DataFrame({
33
- 'provincia':['AR-C','AR-K','AR-Q','AR-R','AR-S','AR-U'],
34
- 'provincia_nombre':['Ciudad Autónoma de Buenos Aires','Catamarca','Neuquén','Río Negro','Santa Fe','Chubut']
35
- })
36
- stores = pd.merge(stores,provinces_dataframe, on='provincia',how='inner')
37
-
38
- provinces_list = ['Ciudad Autónoma de Buenos Aires','Catamarca','Neuquén','Río Negro','Santa Fe','Chubut']
39
- sucursales_seleccionadas = st.multiselect('Selecciona provincias de interes', provinces_list)
40
-
41
- for sucursal_seleccionada in sucursales_seleccionadas:
42
- #st.write(f'**{sucursal_seleccionada}**')
43
- province_code = provinces_dict[sucursal_seleccionada]
44
- stores_selected = stores[stores['provincia']==province_code]
45
- stores_selected = stores_selected[['banderaDescripcion','direccion', 'localidad']]
46
- stores_selected.columns = ['Marca','Direccion', 'Localidad']
47
-
48
- province_codes = [provinces_dict[sucursal_seleccionada] for sucursal_seleccionada in sucursales_seleccionadas]
49
-
50
- selected_provinces = stores[stores['provincia'].isin(province_codes)]
51
-
52
- st.map(selected_provinces,latitude='lat', longitude='lng')
53
-
54
- st.divider()
55
-
56
- st.subheader("Producto elegido:")
57
- st.write("Endulzante Stevia en Sobres Ledesma 50 Un")
58
- st.image("images/ledesma50u.png", width=250)
59
-
60
- store_codes = selected_provinces['sucursalId'].tolist()
61
- # Seleccion de productos por provincia
62
- product_stores_filtered = product_stores[product_stores['id_sucursal'].isin(store_codes) & (product_stores['presentacion_producto'] == '50.0 un')]
63
-
64
-
65
- product_stores_filtered.rename(columns={'id_sucursal': 'sucursalId'}, inplace=True)
66
- product_stores_filtered = pd.merge(product_stores_filtered, stores, on='sucursalId', how='inner')
67
-
68
- #filtrado de vuelta porque aparentemente las referencias de los storesids estan repetidas entre tiendas de distintas provincias
69
- product_stores_filtered = product_stores_filtered[product_stores_filtered['provincia'].isin(province_codes)]
70
- #st.write(product_stores_filtered)
71
- st.divider()
72
- st.subheader("Comparacion de precios")
73
-
74
- st.bar_chart(product_stores_filtered,x='provincia_nombre',y='precio_lista', color='nombre_producto', stack=False, y_label='Precio', x_label='Provincia', horizontal=False, height=500)
75
- st.divider()
76
- st.subheader("Historico de variacion de precios de ledesma y competencia")
77
-
78
-
79
-
80
- # Convertir el string CSV en un DataFrame
81
-
82
- df = pd.read_csv("historico_precios.csv")
83
-
84
- # Convertir la columna 'fecha' a tipo datetime
85
- df['fecha'] = pd.to_datetime(df['fecha'], format='%d-%m-%Y')
86
-
87
- # Colores específicos
88
- highlight_product = "Endulzante Stevia en Sobres Ledesma 50 Un"
89
- highlight_color = '#1f77b4' # Azul
90
- # Colores personalizados para los productos secundarios
91
- secondary_colors = ['#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22']
92
-
93
- # Establecer un estilo más moderno
94
- plt.style.use('fast')
95
-
96
- # Crear el gráfico de líneas
97
- fig, ax = plt.subplots(figsize=(10, 6))
98
-
99
-
100
- # Dibujar todas las líneas con colores distintos
101
- for i, producto in enumerate(df['producto'].unique()):
102
- if producto != highlight_product:
103
- subset = df[df['producto'] == producto]
104
- ax.plot(subset['fecha'], subset['precio'], label=producto, color=secondary_colors[i % len(secondary_colors)], alpha=0.5)
105
-
106
- # Dibujar la línea del producto principal al final
107
- subset = df[df['producto'] == highlight_product]
108
- ax.plot(subset['fecha'], subset['precio'], marker='o', label=highlight_product, color=highlight_color, linewidth=3)
109
-
110
- # Mejorar la visualización
111
- ax.set_ylabel('Precio', fontsize=14)
112
- #ax.set_title('Precio de Productos a lo Largo del Tiempo', fontsize=16)
113
-
114
- # Colocar la leyenda abajo del área del gráfico
115
- ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.20), fontsize=10, ncol=2)
116
- # Ajustar los ticks del eje x para mostrar todas las fechas
117
- ax.set_xticks(df['fecha'])
118
- ax.set_xticklabels(df['fecha'].dt.strftime('%d-%m-%Y'), rotation=45, ha='right')
119
-
120
- # Ajustar el diseño para que la leyenda no se corte
121
- plt.tight_layout()
122
- ax.grid(True, linestyle='--', color='gray', alpha=0.17)
123
-
124
- # Mostrar el gráfico en Streamlit
125
- st.pyplot(fig)
126
-
127
- st.divider()
128
- import streamlit.components.v1 as components
129
- components.html("""
130
- <head>
131
- <meta charset="UTF-8">
132
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
133
- <title>Monitoreo de Precios</title>
134
- <style>
135
- body {
136
- font-family: Arial, sans-serif;
137
- margin: 0;
138
- }
139
- .container {
140
- background-color: white;
141
-
142
- margin: auto;
143
- }
144
- .product-image {
145
- display: flex;
146
- align-items: center;
147
- justify-content: space-between;
148
- }
149
- .product-image img {
150
- width: 150px;
151
- }
152
- .price-current {
153
- font-size: 1.5rem;
154
- font-weight: bold;
155
- margin-top: 10px;
156
- }
157
- .table-container {
158
- margin-top: 20px;
159
- }
160
- table {
161
- width: 100%;
162
- border-collapse: collapse;
163
- }
164
- table th, table td {
165
- padding: 12px;
166
- text-align: left;
167
- border-bottom: 1px solid #ddd;
168
- }
169
- table th {
170
- background-color: #f9f9f9;
171
- }
172
- .price-up {
173
- color: red;
174
- font-weight: bold;
175
- }
176
- .price-down {
177
- color: green;
178
- font-weight: bold;
179
- }
180
- .available {
181
- color: green;
182
- }
183
- .not-available {
184
- color: rgb(255, 0, 0);
185
- }
186
- .store-logo {
187
- width: 24px;
188
- vertical-align: middle;
189
- margin-right: 10px;
190
- }
191
- </style>
192
- </head>
193
- <body>
194
- <div class="container">
195
- <div class="product-image">
196
- <div>
197
- <h2>Monitoreo de Precios de Azucar ledesma 1 kg</h2>
198
- <p class="price-current">Precio actual: $970,00</p>
199
- </div>
200
- <img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/azucar-logo.png" alt="Scooter">
201
- </div>
202
-
203
- <div class="table-container">
204
- <h3>Comparativa de precios</h3>
205
- <table>
206
- <thead>
207
- <tr>
208
- <th>Tienda</th>
209
- <th>Precio</th>
210
- <th>Cambio (%)</th>
211
- <th>Stock</th>
212
- </tr>
213
- </thead>
214
- <tbody>
215
- <tr>
216
- <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/carrefour-Logo.png" alt="Carrefour" class="store-logo"> Carrefour</td>
217
- <td>$1100</td>
218
- <td class="price-up">+13.4%</td>
219
- <td class="available">Disponible</td>
220
- </tr>
221
- <tr>
222
- <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/disco.png" alt="Disco" class="store-logo">Disco</td>
223
- <td>$950</td>
224
- <td class="price-down">-2.7%</td>
225
- <td class="not-available">No disponible</td>
226
-
227
- </tr>
228
- <tr>
229
- <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/vea.png" alt="Vea" class="store-logo">Vea</td>
230
- <td>$1050</td>
231
- <td class="price-up">+8.2%</td>
232
- <td class="available">Disponible</td>
233
-
234
- </tr>
235
- </tbody>
236
- </table>
237
- </div>
238
- </div>
239
- </body>
240
-
241
- """
242
- , height=600)
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import matplotlib.pyplot as plt
4
+
5
+ st.image("images/ledesma-logo.png")
6
+ st.title('Demo monitoreo de precios')
7
+ st.divider()
8
+
9
+ st.subheader("Sucursales:")
10
+ st.write("Seleccionamos arbitrariamente algunas regiones del pais, e incluimos algunas cadenas de supermercados en cada una de ellas")
11
+
12
+ df = pd.read_csv("products.csv")
13
+ df_historic = pd.read_csv("historico_precios.csv")
14
+
15
+ product_stores = pd.read_csv("Store-Products.csv")
16
+ stores = pd.read_csv("sucursales.csv")
17
+ provinces = stores['provincia'].unique()
18
+ provinces_dict = {
19
+ 'Ciudad Autónoma de Buenos Aires': 'AR-C',
20
+ 'La Rioja': 'AR-F',
21
+ 'Santiago del Estero': 'AR-G',
22
+ 'Catamarca': 'AR-K',
23
+ 'Neuquén': 'AR-Q',
24
+ 'Río Negro': 'AR-R',
25
+ 'Santa Fe': 'AR-S',
26
+ 'Tucumán': 'AR-T',
27
+ 'Chubut': 'AR-U',
28
+ 'Córdoba': 'AR-X',
29
+ 'Santa Cruz': 'AR-Z'
30
+ }
31
+
32
+ provinces_dataframe = pd.DataFrame({
33
+ 'provincia':['AR-C','AR-K','AR-Q','AR-R','AR-S','AR-U'],
34
+ 'provincia_nombre':['Ciudad Autónoma de Buenos Aires','Catamarca','Neuquén','Río Negro','Santa Fe','Chubut']
35
+ })
36
+ stores = pd.merge(stores,provinces_dataframe, on='provincia',how='inner')
37
+
38
+ provinces_list = ['Ciudad Autónoma de Buenos Aires','Catamarca','Neuquén','Río Negro','Santa Fe','Chubut']
39
+ sucursales_seleccionadas = st.multiselect('Selecciona provincias de interes', provinces_list)
40
+
41
+ for sucursal_seleccionada in sucursales_seleccionadas:
42
+ #st.write(f'**{sucursal_seleccionada}**')
43
+ province_code = provinces_dict[sucursal_seleccionada]
44
+ stores_selected = stores[stores['provincia']==province_code]
45
+ stores_selected = stores_selected[['banderaDescripcion','direccion', 'localidad']]
46
+ stores_selected.columns = ['Marca','Direccion', 'Localidad']
47
+
48
+ province_codes = [provinces_dict[sucursal_seleccionada] for sucursal_seleccionada in sucursales_seleccionadas]
49
+
50
+ selected_provinces = stores[stores['provincia'].isin(province_codes)]
51
+
52
+ st.map(selected_provinces,latitude='lat', longitude='lng', color="#00a3e0")
53
+
54
+ st.divider()
55
+
56
+ st.subheader("Producto elegido")
57
+ st.write("Endulzante Stevia en Sobres Ledesma 50 Un")
58
+ st.image("images/ledesma50u.png", width=250)
59
+
60
+ store_codes = selected_provinces['sucursalId'].tolist()
61
+ # Seleccion de productos por provincia
62
+ product_stores_filtered = product_stores[product_stores['id_sucursal'].isin(store_codes) & (product_stores['presentacion_producto'] == '50.0 un')]
63
+
64
+
65
+ product_stores_filtered.rename(columns={'id_sucursal': 'sucursalId'}, inplace=True)
66
+ product_stores_filtered = pd.merge(product_stores_filtered, stores, on='sucursalId', how='inner')
67
+
68
+ #filtrado de vuelta porque aparentemente las referencias de los storesids estan repetidas entre tiendas de distintas provincias
69
+ product_stores_filtered = product_stores_filtered[product_stores_filtered['provincia'].isin(province_codes)]
70
+ #st.write(product_stores_filtered)
71
+
72
+ st.divider()
73
+ import streamlit.components.v1 as components
74
+ st.subheader("Monitoreo de precios")
75
+ components.html("""
76
+ <head>
77
+ <meta charset="UTF-8">
78
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
79
+ <title>Monitoreo de Precios</title>
80
+ <style>
81
+ body {
82
+ font-family: sans-serif;
83
+ margin: 0;
84
+ color: rgb(49, 51, 63);
85
+ }
86
+ h3 {
87
+ font-family: "Source Sans Pro", sans-serif;
88
+ font-weight: 300;
89
+ color: rgb(49, 51, 63);
90
+ letter-spacing: -0.005em;
91
+ padding: 0.5rem 0px 1rem;
92
+ margin: 0px;
93
+ line-height: 1.2;
94
+ }
95
+ .container {
96
+ background-color: white;
97
+
98
+ margin: auto;
99
+ }
100
+ .product-image {
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: space-between;
104
+ }
105
+ .product-image img {
106
+ width: 150px;
107
+ }
108
+ .price-current {
109
+ font-size: 1.2rem;
110
+ margin-top: 10px;
111
+ }
112
+ .table-container {
113
+ margin-top: 20px;
114
+ }
115
+ table {
116
+ width: 100%;
117
+ border-collapse: collapse;
118
+ }
119
+ table th, table td {
120
+ padding: 12px;
121
+ text-align: left;
122
+ border-bottom: 1px solid #ddd;
123
+ }
124
+ table th {
125
+ background-color: #f9f9f9;
126
+ }
127
+ .price-up {
128
+ color: red;
129
+ font-weight: bold;
130
+ }
131
+ .price-down {
132
+ color: green;
133
+ font-weight: bold;
134
+ }
135
+ .available {
136
+ color: green;
137
+ }
138
+ .not-available {
139
+ color: rgb(255, 0, 0);
140
+ }
141
+ .store-logo {
142
+ width: 24px;
143
+ vertical-align: middle;
144
+ margin-right: 10px;
145
+ }
146
+ </style>
147
+ </head>
148
+ <body>
149
+ <div class="container">
150
+ <div class="product-image">
151
+ <div>
152
+ <h3>Endulzante Stevia en Sobres Ledesma 50 Un</h3>
153
+ <p class="price-current">Precio actual: <b>$970,00</b></p>
154
+ </div>
155
+ <img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/ledesma50u.png" alt="Scooter">
156
+ </div>
157
+
158
+ <div class="table-container">
159
+ <table>
160
+ <thead>
161
+ <tr>
162
+ <th>Tienda</th>
163
+ <th>Precio</th>
164
+ <th>Cambio (24h)</th>
165
+ <th>Stock</th>
166
+ </tr>
167
+ </thead>
168
+ <tbody>
169
+ <tr>
170
+ <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/carrefour-Logo.png" alt="Carrefour" class="store-logo"> Carrefour</td>
171
+ <td>$1100</td>
172
+ <td class="price-up">+13.4%</td>
173
+ <td class="available">Disponible</td>
174
+ </tr>
175
+ <tr>
176
+ <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/disco.png" alt="Disco" class="store-logo">Disco</td>
177
+ <td>$950</td>
178
+ <td class="price-down">-2.7%</td>
179
+ <td class="not-available">No disponible</td>
180
+
181
+ </tr>
182
+ <tr>
183
+ <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/vea.png" alt="Vea" class="store-logo">Vea</td>
184
+ <td>$1050</td>
185
+ <td class="price-up">+8.2%</td>
186
+ <td class="available">Disponible</td>
187
+
188
+ </tr>
189
+ </tbody>
190
+ </table>
191
+ </div>
192
+ </div>
193
+ </body>
194
+
195
+ """
196
+ , height=450)
197
+ st.divider()
198
+ st.subheader("Comparacion de precios")
199
+
200
+ st.bar_chart(product_stores_filtered,x='provincia_nombre',y='precio_lista', color='nombre_producto', stack=False, y_label='Precio', x_label='Provincia', horizontal=False, height=500)
201
+ st.divider()
202
+ st.subheader("Historico de variacion de precios de ledesma y competencia")
203
+
204
+
205
+
206
+ # Convertir el string CSV en un DataFrame
207
+
208
+ df = pd.read_csv("historico_precios.csv")
209
+
210
+ # Convertir la columna 'fecha' a tipo datetime
211
+ df['fecha'] = pd.to_datetime(df['fecha'], format='%d-%m-%Y')
212
+
213
+ # Colores específicos
214
+ highlight_product = "Endulzante Stevia en Sobres Ledesma 50 Un"
215
+ highlight_color = '#1f77b4' # Azul
216
+ # Colores personalizados para los productos secundarios
217
+ secondary_colors = ['#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22']
218
+
219
+ # Establecer un estilo más moderno
220
+ plt.style.use('fast')
221
+
222
+ # Crear el gráfico de líneas
223
+ fig, ax = plt.subplots(figsize=(10, 6))
224
+
225
+
226
+ # Dibujar todas las líneas con colores distintos
227
+ for i, producto in enumerate(df['producto'].unique()):
228
+ if producto != highlight_product:
229
+ subset = df[df['producto'] == producto]
230
+ ax.plot(subset['fecha'], subset['precio'], label=producto, color=secondary_colors[i % len(secondary_colors)], alpha=0.5)
231
+
232
+ # Dibujar la línea del producto principal al final
233
+ subset = df[df['producto'] == highlight_product]
234
+ ax.plot(subset['fecha'], subset['precio'], marker='o', label=highlight_product, color=highlight_color, linewidth=3)
235
+
236
+ # Mejorar la visualización
237
+ ax.set_ylabel('Precio', fontsize=14)
238
+ #ax.set_title('Precio de Productos a lo Largo del Tiempo', fontsize=16)
239
+
240
+ # Colocar la leyenda abajo del área del gráfico
241
+ ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.20), fontsize=10, ncol=2)
242
+ # Ajustar los ticks del eje x para mostrar todas las fechas
243
+ ax.set_xticks(df['fecha'])
244
+ ax.set_xticklabels(df['fecha'].dt.strftime('%d-%m-%Y'), rotation=45, ha='right')
245
+
246
+ # Ajustar el diseño para que la leyenda no se corte
247
+ plt.tight_layout()
248
+ ax.grid(True, linestyle='--', color='gray', alpha=0.17)
249
+
250
+ # Mostrar el gráfico en Streamlit
251
+ st.pyplot(fig)
252
+