Spaces:
Build error
Build error
| import streamlit as st | |
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| st.image("images/ledesma-logo.png") | |
| st.title('Demo monitoreo de precios') | |
| st.divider() | |
| st.subheader("Sucursales:") | |
| st.write("Seleccionamos arbitrariamente algunas regiones del pais, e incluimos algunas cadenas de supermercados en cada una de ellas") | |
| df = pd.read_csv("products.csv") | |
| df_historic = pd.read_csv("historico_precios.csv") | |
| product_stores = pd.read_csv("Store-Products.csv") | |
| stores = pd.read_csv("sucursales.csv") | |
| provinces = stores['provincia'].unique() | |
| provinces_dict = { | |
| 'Ciudad Autónoma de Buenos Aires': 'AR-C', | |
| 'La Rioja': 'AR-F', | |
| 'Santiago del Estero': 'AR-G', | |
| 'Catamarca': 'AR-K', | |
| 'Neuquén': 'AR-Q', | |
| 'Río Negro': 'AR-R', | |
| 'Santa Fe': 'AR-S', | |
| 'Tucumán': 'AR-T', | |
| 'Chubut': 'AR-U', | |
| 'Córdoba': 'AR-X', | |
| 'Santa Cruz': 'AR-Z' | |
| } | |
| provinces_dataframe = pd.DataFrame({ | |
| 'provincia':['AR-C','AR-K','AR-Q','AR-R','AR-S','AR-U'], | |
| 'provincia_nombre':['Ciudad Autónoma de Buenos Aires','Catamarca','Neuquén','Río Negro','Santa Fe','Chubut'] | |
| }) | |
| stores = pd.merge(stores,provinces_dataframe, on='provincia',how='inner') | |
| provinces_list = ['Ciudad Autónoma de Buenos Aires','Catamarca','Neuquén','Río Negro','Santa Fe','Chubut'] | |
| sucursales_seleccionadas = st.multiselect('Selecciona provincias de interes', provinces_list) | |
| for sucursal_seleccionada in sucursales_seleccionadas: | |
| #st.write(f'**{sucursal_seleccionada}**') | |
| province_code = provinces_dict[sucursal_seleccionada] | |
| stores_selected = stores[stores['provincia']==province_code] | |
| stores_selected = stores_selected[['banderaDescripcion','direccion', 'localidad']] | |
| stores_selected.columns = ['Marca','Direccion', 'Localidad'] | |
| province_codes = [provinces_dict[sucursal_seleccionada] for sucursal_seleccionada in sucursales_seleccionadas] | |
| selected_provinces = stores[stores['provincia'].isin(province_codes)] | |
| st.map(selected_provinces,latitude='lat', longitude='lng', color="#00a3e0") | |
| st.divider() | |
| st.subheader("Producto elegido") | |
| st.write("Endulzante Stevia en Sobres Ledesma 50 Un") | |
| st.image("images/ledesma50u.png", width=250) | |
| store_codes = selected_provinces['sucursalId'].tolist() | |
| # Seleccion de productos por provincia | |
| product_stores_filtered = product_stores[product_stores['id_sucursal'].isin(store_codes) & (product_stores['presentacion_producto'] == '50.0 un')] | |
| product_stores_filtered.rename(columns={'id_sucursal': 'sucursalId'}, inplace=True) | |
| product_stores_filtered = pd.merge(product_stores_filtered, stores, on='sucursalId', how='inner') | |
| #filtrado de vuelta porque aparentemente las referencias de los storesids estan repetidas entre tiendas de distintas provincias | |
| product_stores_filtered = product_stores_filtered[product_stores_filtered['provincia'].isin(province_codes)] | |
| #st.write(product_stores_filtered) | |
| st.divider() | |
| import streamlit.components.v1 as components | |
| st.subheader("Monitoreo de precios") | |
| components.html(""" | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Monitoreo de Precios</title> | |
| <style> | |
| body { | |
| font-family: sans-serif; | |
| margin: 0; | |
| color: rgb(49, 51, 63); | |
| } | |
| h3 { | |
| font-family: "Source Sans Pro", sans-serif; | |
| font-weight: 300; | |
| color: rgb(49, 51, 63); | |
| letter-spacing: -0.005em; | |
| padding: 0.5rem 0px 1rem; | |
| margin: 0px; | |
| line-height: 1.2; | |
| } | |
| .container { | |
| background-color: white; | |
| margin: auto; | |
| } | |
| .product-image { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| .product-image img { | |
| width: 150px; | |
| } | |
| .price-current { | |
| font-size: 1.2rem; | |
| margin-top: 10px; | |
| } | |
| .table-container { | |
| margin-top: 20px; | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| } | |
| table th, table td { | |
| padding: 12px; | |
| text-align: left; | |
| border-bottom: 1px solid #ddd; | |
| } | |
| table th { | |
| background-color: #f9f9f9; | |
| } | |
| .price-up { | |
| color: red; | |
| font-weight: bold; | |
| } | |
| .price-down { | |
| color: green; | |
| font-weight: bold; | |
| } | |
| .available { | |
| color: green; | |
| } | |
| .not-available { | |
| color: rgb(255, 0, 0); | |
| } | |
| .store-logo { | |
| width: 24px; | |
| vertical-align: middle; | |
| margin-right: 10px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="product-image"> | |
| <div> | |
| <h3>Endulzante Stevia en Sobres Ledesma 50 Un</h3> | |
| <p class="price-current">Precio actual: <b>$970,00</b></p> | |
| </div> | |
| <img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/ledesma50u.png" alt="Scooter"> | |
| </div> | |
| <div class="table-container"> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Tienda</th> | |
| <th>Precio</th> | |
| <th>Cambio (24h)</th> | |
| <th>Stock</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/carrefour-Logo.png" alt="Carrefour" class="store-logo"> Carrefour</td> | |
| <td>$1100</td> | |
| <td class="price-up">+13.4%</td> | |
| <td class="available">Disponible</td> | |
| </tr> | |
| <tr> | |
| <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/disco.png" alt="Disco" class="store-logo">Disco</td> | |
| <td>$950</td> | |
| <td class="price-down">-2.7%</td> | |
| <td class="not-available">No disponible</td> | |
| </tr> | |
| <tr> | |
| <td><img src=" https://huggingface.co/spaces/GianJSX/precios-demo/resolve/main/images/vea.png" alt="Vea" class="store-logo">Vea</td> | |
| <td>$1050</td> | |
| <td class="price-up">+8.2%</td> | |
| <td class="available">Disponible</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </body> | |
| """ | |
| , height=450) | |
| st.divider() | |
| st.subheader("Comparacion de precios") | |
| 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) | |
| st.divider() | |
| st.subheader("Historico de variacion de precios de ledesma y competencia") | |
| # Convertir el string CSV en un DataFrame | |
| df = pd.read_csv("historico_precios.csv") | |
| # Convertir la columna 'fecha' a tipo datetime | |
| df['fecha'] = pd.to_datetime(df['fecha'], format='%d-%m-%Y') | |
| # Colores específicos | |
| highlight_product = "Endulzante Stevia en Sobres Ledesma 50 Un" | |
| highlight_color = '#1f77b4' # Azul | |
| # Colores personalizados para los productos secundarios | |
| secondary_colors = ['#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22'] | |
| # Establecer un estilo más moderno | |
| plt.style.use('fast') | |
| # Crear el gráfico de líneas | |
| fig, ax = plt.subplots(figsize=(10, 6)) | |
| # Dibujar todas las líneas con colores distintos | |
| for i, producto in enumerate(df['producto'].unique()): | |
| if producto != highlight_product: | |
| subset = df[df['producto'] == producto] | |
| ax.plot(subset['fecha'], subset['precio'], label=producto, color=secondary_colors[i % len(secondary_colors)], alpha=0.5) | |
| # Dibujar la línea del producto principal al final | |
| subset = df[df['producto'] == highlight_product] | |
| ax.plot(subset['fecha'], subset['precio'], marker='o', label=highlight_product, color=highlight_color, linewidth=3) | |
| # Mejorar la visualización | |
| ax.set_ylabel('Precio', fontsize=14) | |
| #ax.set_title('Precio de Productos a lo Largo del Tiempo', fontsize=16) | |
| # Colocar la leyenda abajo del área del gráfico | |
| ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.20), fontsize=10, ncol=2) | |
| # Ajustar los ticks del eje x para mostrar todas las fechas | |
| ax.set_xticks(df['fecha']) | |
| ax.set_xticklabels(df['fecha'].dt.strftime('%d-%m-%Y'), rotation=45, ha='right') | |
| # Ajustar el diseño para que la leyenda no se corte | |
| plt.tight_layout() | |
| ax.grid(True, linestyle='--', color='gray', alpha=0.17) | |
| # Mostrar el gráfico en Streamlit | |
| st.pyplot(fig) | |