CSVExcelReader / app.py
VicGerardoPR's picture
Update app.py
4661fa3 verified
raw
history blame
6.11 kB
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import io
import base64
from PIL import Image
# Configuraci贸n de la p谩gina
st.set_page_config(
page_title="Visualizador de Datos",
page_icon="馃搳",
layout="wide"
)
# T铆tulo de la aplicaci贸n
st.title("馃搳 Visualizador de Datos")
st.markdown("### Carga tu archivo CSV o Excel y crea visualizaciones personalizadas")
# Funci贸n para cargar el archivo
def load_data():
uploaded_file = st.file_uploader("Carga tu archivo CSV o Excel", type=["csv", "xlsx", "xls"])
if uploaded_file is not None:
try:
# Determinar el tipo de archivo y cargarlo
if uploaded_file.name.endswith('.csv'):
data = pd.read_csv(uploaded_file)
else:
data = pd.read_excel(uploaded_file)
return data
except Exception as e:
st.error(f"Error al cargar el archivo: {e}")
return None
return None
# Funci贸n para generar gr谩ficos
def create_plot(data, x_col, y_col, plot_type):
fig, ax = plt.subplots(figsize=(10, 6))
if plot_type == "Barras":
sns.barplot(x=x_col, y=y_col, data=data, ax=ax)
elif plot_type == "Barras (Count)":
# Crear conteo de valores
count_data = data[x_col].value_counts().reset_index()
count_data.columns = [x_col, 'count']
sns.barplot(x=x_col, y='count', data=count_data, ax=ax)
plt.ylabel('Frecuencia')
elif plot_type == "L铆neas":
sns.lineplot(x=x_col, y=y_col, data=data, ax=ax)
elif plot_type == "Dispersi贸n":
sns.scatterplot(x=x_col, y=y_col, data=data, ax=ax)
elif plot_type == "Histograma":
sns.histplot(data[x_col], ax=ax)
plt.xlabel(x_col)
elif plot_type == "Boxplot":
sns.boxplot(x=x_col, y=y_col, data=data, ax=ax)
elif plot_type == "Viol铆n":
sns.violinplot(x=x_col, y=y_col, data=data, ax=ax)
elif plot_type == "Pastel":
data[x_col].value_counts().plot.pie(autopct='%1.1f%%', ax=ax)
plt.ylabel('')
elif plot_type == "Mapa de calor":
if len(data) > 100:
sample_data = data.sample(100)
else:
sample_data = data
correlation = sample_data.select_dtypes(include=['float64', 'int64']).corr()
sns.heatmap(correlation, annot=True, cmap='coolwarm', ax=ax)
plt.tight_layout()
return fig
# Funci贸n para descargar im谩genes
def get_image_download_link(fig, filename, text):
buf = io.BytesIO()
fig.savefig(buf, format='png', dpi=300, bbox_inches='tight')
buf.seek(0)
b64 = base64.b64encode(buf.read()).decode()
href = f'<a href="data:image/png;base64,{b64}" download="{filename}.png">{text}</a>'
return href
# Funci贸n principal
def main():
# Cargar datos
data = load_data()
if data is not None:
# Mostrar informaci贸n b谩sica del dataset
st.subheader("Vista previa de los datos")
st.dataframe(data.head())
st.subheader("Informaci贸n del dataset")
col1, col2 = st.columns(2)
with col1:
st.info(f"N煤mero de filas: {data.shape[0]}")
with col2:
st.info(f"N煤mero de columnas: {data.shape[1]}")
# Selecci贸n de columnas y tipo de gr谩fico
st.subheader("Crear visualizaci贸n")
col1, col2, col3 = st.columns(3)
with col1:
plot_type = st.selectbox(
"Tipo de gr谩fico",
["Barras", "Barras (Count)", "L铆neas", "Dispersi贸n", "Histograma", "Boxplot", "Viol铆n", "Pastel", "Mapa de calor"]
)
# Opciones de columnas basadas en el tipo de gr谩fico
numeric_cols = data.select_dtypes(include=['float64', 'int64']).columns.tolist()
categorical_cols = data.select_dtypes(include=['object']).columns.tolist()
all_cols = data.columns.tolist()
with col2:
if plot_type == "Histograma":
x_col = st.selectbox("Selecciona la columna para el histograma", numeric_cols)
y_col = None
elif plot_type == "Mapa de calor":
x_col = "Correlaci贸n"
y_col = "Correlaci贸n"
elif plot_type == "Pastel":
x_col = st.selectbox("Selecciona la columna para el gr谩fico de pastel", categorical_cols if categorical_cols else all_cols)
y_col = None
elif plot_type == "Barras (Count)":
x_col = st.selectbox("Selecciona la columna para contar frecuencias", all_cols)
y_col = "count" # Valor especial para indicar que se usar谩 conteo
else:
x_options = categorical_cols + numeric_cols if categorical_cols else all_cols
x_col = st.selectbox("Selecciona la columna para el eje X", x_options)
with col3:
if plot_type not in ["Histograma", "Pastel", "Mapa de calor", "Barras (Count)"]:
y_col = st.selectbox("Selecciona la columna para el eje Y", numeric_cols if numeric_cols else all_cols)
# Crear gr谩fico
if st.button("Generar visualizaci贸n"):
try:
st.subheader("Visualizaci贸n")
fig = create_plot(data, x_col, y_col, plot_type)
st.pyplot(fig)
# Bot贸n para descargar la imagen
st.markdown(
get_image_download_link(
fig,
f"{plot_type}_{x_col}_{y_col if y_col else ''}",
"馃摜 Descargar imagen"
),
unsafe_allow_html=True
)
except Exception as e:
st.error(f"Error al generar el gr谩fico: {e}")
st.info("Sugerencia: Verifica que las columnas seleccionadas sean compatibles con el tipo de gr谩fico.")
# Ejecutar la aplicaci贸n
if __name__ == "__main__":
main()