Commit 686c6bea by Itzel Camacho

Glucometro con comidas y estadísticas de las comidas usando el archivo test.csv

parent c87514ad
import pandas as pd
from dash import Dash, Input, Output, dcc, html, callback
import plotly.graph_objects as go
import plotly.express as px
import plotly.figure_factory as ff
import requests
import numpy as np
from plotly.subplots import make_subplots
from sklearn.cluster import KMeans
from scipy import stats
from ast import literal_eval
from funciones_comidas import readGlucosa
from funciones_comidas import readVisitas
import flask
server = flask.Flask(__name__)
def update_correlacion_macro_iauc():
datos = comidas.sort_values(by="iAUC", ascending=True)
datos = datos[np.abs(stats.zscore(datos["iAUC"], nan_policy='omit'))<3]
datos.reset_index(inplace=True)
metricas = ["hc_total", "lipids_total","protein_total","fiber_total"]
pcts = [ metrica + "_pct" for metrica in metricas]
datos["total"] = datos[metricas].sum(axis=1)
datos = datos[datos["total"]>0]
datos[pcts] = datos[metricas].div(datos["total"], axis=0)
fig = make_subplots(rows=2, cols=4, vertical_spacing=0.25)
lcol = 1
seq = 1
for metrica in metricas:
datosfil = datos[np.abs(stats.zscore(datos[metrica], nan_policy='omit')) < 3]
fig.add_trace(
go.Scatter(x=datosfil["iAUC"], y=datosfil[metrica], name=metrica, mode='markers'),
row=1, col=lcol
)
fig.add_trace(
go.Scatter(x=datosfil["iAUC"], y=datosfil[metrica + "_pct"], name=metrica, mode='markers'),
row=2, col=lcol
)
fig["layout"]['xaxis' + str(seq)]['title']="iAUC"
fig["layout"]['yaxis' + str(seq)]['title']= metrica
fig["layout"]['xaxis' + str(seq + 4)]['title']="iAUC"
fig["layout"]['yaxis' + str(seq + 4)]['title']= "pct de " + metrica
lcol = lcol + 1
seq = seq + 1
return fig
def comidas_iaucs(datos):
columnas = ["pre-AUC", "post-AUC", "iAUC"]
datos["N-alimentos"] = datos["foods"].apply(lambda x: len(x))
fig = make_subplots(cols=3, rows=1, vertical_spacing=0.25)
lcol = 1
seq = 1
for columna in columnas:
datosfil = datos[np.abs(stats.zscore(datos[columna], nan_policy='omit')) < 3]
fig.add_trace(
go.Scatter(y=datosfil[columna], name=columna, mode="markers"),
row=1, col=lcol
)
fig['layout']['yaxis' + str(seq)]['title']=columna
fig['layout']['xaxis' + str(seq)]['title']="Comida ID"
seq = seq + 1
lcol = lcol + 1
fig.update_layout(showlegend=False)
return fig
def comidas_iauc_describe(datos):
columnas = ["pre-AUC", "post-AUC", "iAUC"]
fig = make_subplots(cols=3, rows=1, vertical_spacing=0.25)
seq = 1
lcol = 1
for columna in columnas:
datosfil = datos[np.abs(stats.zscore(datos[columna], nan_policy='omit')) < 3]
fig.add_trace(
go.Histogram(x=datosfil[columna], name=columna),
row=1, col=lcol
)
fig['layout']['yaxis' + str(seq)]['title']=columna
seq = seq + 1
lcol = lcol + 1
fig.update_layout(
showlegend = False,
bargap=0.05, # gap between bars of adjacent location coordinates
bargroupgap=0.05 # gap between bars of the same location coordinates
)
return fig
def comidas_macro_contenido(datos):
columnas = ["hc_total", "lipids_total", "fiber_total", "protein_total"]
datos["N-alimentos"] = datos["foods"].apply(lambda x: len(x))
figura = make_subplots(cols=4, rows=1, vertical_spacing=0.24)
lcol = 1
seq = 1
for columna in columnas:
datosfil = datos[np.abs(stats.zscore(datos[columna], nan_policy='omit')) < 3]
figura.add_trace(
go.Scatter(y=datosfil[columna], name=columna, mode="markers"),
row=1, col=lcol
)
figura['layout']['yaxis' + str(seq)]['title']=columna
figura['layout']['xaxis' + str(seq)]['title']="Comida ID"
seq = seq + 1
lcol = lcol + 1 if lcol < 4 else 1
figura.update_layout(showlegend=False)
return figura
def comidas_macro_describe(datos):
columnas = ["hc_total", "lipids_total", "fiber_total", "protein_total"]
fig = make_subplots(cols=4, rows=1, vertical_spacing=0.25)
seq = 1
lcol = 1
for columna in columnas:
datosfil = datos[np.abs(stats.zscore(datos[columna], nan_policy='omit')) < 3]
fig.add_trace(
go.Histogram(x=datosfil[columna], name=columna),
row=1, col=lcol
)
fig['layout']['yaxis' + str(seq)]['title']=columna
seq = seq + 1
lcol = lcol + 1 if lcol < 4 else 1
fig.update_layout(
showlegend = False,
bargap=0.05, # gap between bars of adjacent location coordinates
bargroupgap=0.05 # gap between bars of the same location coordinates
)
return fig
def comidas_porcentajes(datos):
columnas = ["hc_total", "fiber_total", "protein_total", "lipids_total"]
datos["total"] = datos[columnas].sum(axis=1)
datos = datos[datos["total"]>0]
datos[columnas] = datos[columnas].div(datos["total"], axis=0)
figura = ff.create_distplot([ datos[columna] for columna in columnas], columnas, show_hist = False, show_rug=False)
return figura
def comidas_principales(datos):
dominantes = datos.groupby("dominante").count()
dominantes.sort_values(by="patient", ascending=False, inplace=True)
dominantes = dominantes[dominantes["patient"] > 9]
figura = make_subplots(cols=1, rows=1, subplot_titles= ["Alimentos"])
figura.add_trace(
go.Scatter(x=dominantes.index, y=dominantes["patient"], mode='markers', name="# de comidas"),
col=1, row=1
)
figura["layout"]['yaxis']['title']= "# de comidas"
# figura.update_layout(height=2000, width=800)
return figura
def comidas_principales_categorias(datos):
categorias = datos.groupby("dominante_category").count()
categorias.sort_values(by="patient", ascending=False, inplace=True)
categorias = categorias[categorias["patient"] > 9]
figura = make_subplots(cols=1, rows=1, subplot_titles=["Categorías de alimentos"])
figura.add_trace(
go.Scatter(x=categorias.index, y=categorias["patient"], mode='markers'),
col=1, row=1
)
figura["layout"]['yaxis']['title']= "# de comidas"
return figura
def categorias_promedio_aucs():
categorias = comidas.groupby("dominante_category")[["iAUC","hc_total"]].mean()
#print(categorias)
categorias["tamaño"] = comidas.groupby("dominante_category")["iAUC"].count()
categorias.sort_values(ascending=False, inplace=True, by="iAUC")
# figura = make_subplots(cols=1, rows=1, subplot_titles=["Categorías de alimentos"])
# figura.add_trace(
# go.Scatter(x=categorias.index, y=categorias["iAUC"], mode="markers")
# )
figura = px.scatter(categorias["iAUC"], size=categorias["tamaño"])
return figura
def categorias_aucs(datos):
datos_fil = datos[np.abs(stats.zscore(datos["iAUC"], nan_policy='omit')) < 3]
figura = px.box(datos_fil, x="dominante_category", y="iAUC")
return figura
def aucs_paciente(datos):
figura = px.box(datos, x="patient", y="iAUC")
return figura
def comidas_paciente_datos(datos):
columnas = ["hc_total", "kcal_total", "fiber_total", "protein_total", "lipids_total"]
figura = make_subplots(cols=5, rows=4, subplot_titles=("hc","kcal","fiber", "protein", "lipids"))
lcol = 1
for columna in columnas:
datosfil = datos[np.abs(stats.zscore(datos[columna], nan_policy='omit')) < 3]
figura.add_trace(
go.Scatter(y=datosfil.groupby("patient")[columna].sum(), name="total_" + columna, mode= "markers"),
row=1, col=lcol
)
figura.add_trace(
go.Histogram(x=datosfil.groupby("patient")[columna].sum(), name="total_" + columna),
row=2, col=lcol
)
figura.add_trace(
go.Scatter(y=datosfil.groupby("patient")[columna].mean(), name="promedio_" + columna, mode= "markers"),
row=3, col=lcol
)
figura.add_trace(
go.Histogram(x=datosfil.groupby("patient")[columna].mean(), name="promedio_" + columna),
row=4, col=lcol
)
lcol = lcol + 1
figura.update_layout(showlegend = False)
return figura
def comidas_auc_paciente(datos):
columnas = ["pre-AUC", "post-AUC", "iAUC"]
figura = make_subplots(cols = 4, rows = 2, subplot_titles=("pre-AUC","post-AUC", "iAUC", "N-Comidas"))
lcol = 1
for columna in columnas:
datosfil = datos[np.abs(stats.zscore(datos[columna], nan_policy='omit')) < 3]
figura.add_trace(
go.Scatter(y=datosfil.groupby("patient")[columna].mean(), name="promedio_" + columna, mode= "markers"),
row=1, col=lcol
)
figura.add_trace(
go.Histogram(x=datosfil.groupby("patient")[columna].mean(), name="Distr. " + columna),
row=2, col=lcol
)
lcol = lcol + 1
figura.add_trace(
go.Scatter(y=datosfil.groupby("patient")["iAUC"].count(), name="N-comidas", mode= "markers"),
row = 1, col = 4
)
figura.add_trace(
go.Histogram(x=datosfil.groupby("patient")["iAUC"].count(), name="Distr. N-comidas"),
row = 2, col = 4
)
figura.update_layout(
showlegend = False,
bargap=0.05, # gap between bars of adjacent location coordinates
bargroupgap=0.05 # gap between bars of the same location coordinates
)
return figura
comidas = pd.read_csv("todos-foods.csv", usecols=["hc_total", "kcal_total", "fiber_total",\
"protein_total", "lipids_total","fecha_hora", "patient", "visita", "fecha_visita",\
"glucosa_basal_area", "glucosa_estimulo_area",\
"glucosa_area_efectiva","glucosa_area_relativa","foods","dominante", "dominante_category"])
comidas["foods"] = comidas["foods"].apply(literal_eval)
comidas = comidas[comidas["visita"] == "e1"]
comidas = comidas[comidas["hc_total"]>0]
comidas.rename(columns={"glucosa_basal_area":"pre-AUC", "glucosa_estimulo_area":"post-AUC", "glucosa_area_efectiva":"iAUC"}, inplace=True)
comidas["iAUC"] = comidas["post-AUC"] - comidas["pre-AUC"] * 2
df_total = pd.read_csv("test.csv")
df_total = df_total[df_total["etapas"] == "e1"]
df_total['FH_salto'] = pd.to_datetime(df_total['FH_salto'])
df_total['FH_reportada'] = pd.to_datetime(df_total['FH_reportada'])
df_total['FH_foto'] = pd.to_datetime(df_total['FH_foto'])
external_stylesheets = [
{
"href": (
"https://fonts.googleapis.com/css2?"
"family=Lato:wght@400;700&display=swap"
),
"rel": "stylesheet",
},
]
app = Dash(__name__, external_stylesheets=external_stylesheets, server=server, url_base_pathname='/nutri/estadisticas/')
app.title = "NutrIndMex. Análisis de datos de las comidas."
app.layout = html.Div(children=[
#encabezado
html.Div(children=[
html.P(children="🥑", className="header-emoji"),
html.H1(children="NutrIndMex", className="header-title"),
html.H2(children="Análisis de Datos de las Comidas", className="header-title"),
],
className="header",),
html.Div(children=[
html.Div(children= [ html.H1("Glucosa de los pacientes con Comidas", className= "header-title2"),],
),
]),
dcc.Dropdown(
options=[
{'label': 'Todas las comidas', 'value': '0'},
{'label': '[0-5]', 'value': '[0-5]'},
{'label': '[5-15]', 'value': '[5-15]'},
{'label': '[15-30]', 'value': '[15-30]'},
{'label': '[30-45]', 'value': '[30-45]'},
{'label': '[45-60]', 'value': '[45-60]'},
{'label': '[60-90]', 'value': '[60-90]'},
{'label': '[90-120]', 'value': '[90-120]'},
{'label': '[>120]', 'value': '[>120]'},
],
value='0',
id='rango'
),
dcc.Graph(id='glucosa-graph'),
dcc.Slider(
min=30, max=216, step=1, marks={i: str(i) for i in range(30, 217, 18)},
value=30, tooltip={'always_visible': True}, updatemode='drag', id='slider-patient'
),
html.Div(children= [
html.Div(children= [html.H1("iAUCs de las comidas reportadas", className = "header-title2")]),
dcc.Graph(figure=comidas_iaucs(comidas)),
dcc.Graph(figure=comidas_iauc_describe(comidas))
,]),
# datos de comidas
html.Div(children= [
html.Div(children= [html.H1("Contenido de macronutrientes de las comidas", className = "header-title2")]),
dcc.Graph(figure=comidas_macro_contenido(comidas))
,]),
# descripcion de comidas
html.Div(children= [
html.Div(children= [html.H1("Distribución de Macronutrientes de comidas", className = "header-title2")]),
dcc.Graph(figure=comidas_macro_describe(comidas))
,]),
# descripcion de componentes de macronutrientes de comidas
html.Div(children= [
html.Div(children= [html.H1("Distribución de %s de Macronutrientes de comidas", className = "header-title2")]),
dcc.Graph(figure=comidas_porcentajes(comidas))
,]),
# relación de macronutrientes de comidas con sus iAUC
html.Div(children= [
html.Div(children= [html.H1("Relación de macros / iAUCs de las comidas ", className = "header-title2")]),
dcc.Graph(figure=update_correlacion_macro_iauc())
,]),
# # de comidas por componente dominante
html.Div(children= [
html.Div(children= [html.H1("Distribución de num. de comidas por componente principal", className = "header-title2")]),
dcc.Graph(figure=comidas_principales(comidas)),
dcc.Graph(figure=comidas_principales_categorias(comidas)),
dcc.Graph(figure=categorias_promedio_aucs()),
dcc.Graph(figure=categorias_aucs(comidas))
,]),
# descripcion de comidas por paciente
html.Div(children= [
html.Div(children= [html.H1("Macronutrientes de comidas por paciente", className = "header-title2")]),
dcc.Graph(figure=comidas_paciente_datos(comidas))
,]),
# descripcion de aucs comidas por paciente
html.Div(children= [
html.Div(children= [html.H1("AUCs promedio de comidas por paciente", className = "header-title2")]),
dcc.Graph(figure=comidas_auc_paciente(comidas))
,]),
# descripcion de aucs comidas por paciente
html.Div(children= [
html.Div(children= [html.H1("iAUCs de comidas por paciente", className = "header-title2")]),
dcc.Graph(figure=aucs_paciente(comidas))
,]),
]) # cierre del layout
@callback(
Output('glucosa-graph', 'figure'),
[Input('rango', 'value'),
Input('slider-patient', 'value')]
)
def update_graph(rango_str, selected_pat):
if selected_pat not in df_total['patient']:
return go.Figure()
if not selected_pat or not rango_str:
return {}
patient_foods = df_total.loc[df_total['patient'] == selected_pat]
glucosa = readGlucosa(selected_pat)
visita = readVisitas(1)
fecha_visita1 = pd.to_datetime(visita.loc[visita['id'] == selected_pat, 'visit_date'].iloc[0])
filtered_glucosa = glucosa[(glucosa['date_time'] >= fecha_visita1) &
(glucosa['date_time'] <= fecha_visita1 + pd.Timedelta(days=15))]
# Si no hay datos de glucosa en el rango de tiempo, retornar un gráfico vacío
if filtered_glucosa.empty:
return go.Figure()
fig = go.Figure()
fig.add_trace(go.Scatter(x=filtered_glucosa['date_time'], # gráfica de la glucosa del paciente seleccionado
y=filtered_glucosa['value'],
mode='lines',
name='Glucosa paciente visita 1'))
y_foods = np.interp(patient_foods['FH_reportada'], glucosa['date_time'], glucosa['value']) # interpolar fecha de las comidas con glucosa
distancias = abs((patient_foods['FH_salto'] - patient_foods['FH_reportada']).dt.total_seconds()) / 60
distancias_df = pd.concat([distancias,patient_foods['FH_reportada'], patient_foods['FH_foto']], axis=1, ignore_index=True)
distancias_df.columns = ['Distancia','FH_reportada', 'FH_foto']
y_foto = np.interp(pd.to_numeric(patient_foods['FH_foto']), pd.to_numeric(glucosa['date_time']), # interpolar fecha de la foto con glucosa
glucosa['value'])
# valores del dropdown y separarlos para convertirlos en una lista
if rango_str == '0':
fig.add_trace(go.Scatter(x=patient_foods['FH_reportada'], y=y_foods, mode='markers', name = 'Comida completa', marker=dict(color='red', size=10)))
fig.add_trace(go.Scatter(x=patient_foods['FH_foto'], y=y_foto, mode='markers', name = 'Foto comida', marker=dict(color='yellow', size=8)))
return fig
elif rango_str == '[>120]':
rango = [120, float('inf')]
else:
rango_split = rango_str.strip('[]').split('-')
rango = [int(rango_split[0]), int(rango_split[1])] # rango convertido a lista
distancias_rango = distancias_df[(distancias_df['Distancia'] >= min(rango)) & (distancias_df['Distancia'] <= max(rango))] #elegir las comidas que se encuentran en el rango seleccionado
fotos_wfoods = distancias_rango.set_index('FH_reportada')['FH_foto']
if distancias_rango.empty:
return fig
y_distancias = np.interp(pd.to_numeric(distancias_rango['FH_reportada']), pd.to_numeric(glucosa['date_time']), glucosa['value']) #interpolar la fecha de las distancias con glucosa
y_foto_wfood = np.interp(pd.to_numeric(fotos_wfoods.values), pd.to_numeric(glucosa['date_time']), glucosa['value'])
fig.add_trace(go.Scatter(x=distancias_rango['FH_reportada'],
y=y_distancias,
mode='markers',
name='Comida completa',
marker=dict(color='red', size= 10)))
fig.add_trace(go.Scatter(x=fotos_wfoods.values, y=y_foto_wfood, mode='markers', name = 'Foto comida', marker=dict(color='yellow', size=8)))
fig.update_layout(transition_duration=500)
return fig
if __name__ == "__main__":
app.run_server(debug=True, port=8051, host='0.0.0.0')
\ No newline at end of file
import pandas as pd
import requests
import scipy.stats as stats
from datetime import date,datetime
import numpy as np
import config
from urllib.parse import urlparse
import urllib.request
import requests
from PIL import Image
from PIL.ExifTags import TAGS
import re
url_api = 'https://nutricion.c3.unam.mx/nd'
def readGlucosa(participante, solo_fecha=None):
url_glucosa = url_api + "/patients/" + str(participante) + "/glucouse/data"
try:
df=pd.read_json(url_glucosa, orient='records', convert_dates=False)
if solo_fecha:
df=df[df['date']==solo_fecha]
except:
print("no hay datos de glucosa para ", participante)
return pd.DataFrame()
if not df.empty:
df["date_time"] = df["date"] + "-" + df["time"]
df["date_time"] = pd.to_datetime(df["date_time"])
ordered = df.sort_values(by=["date_time"])
ordered = ordered.reset_index(drop=True)
return ordered[["date_time", "value"]]
else:
return df
def readVisitas(visita):
visita = 1
url_visitas = url_api + "/visits/" + str(visita) + "/patients-data/"
datos = requests.get(url_visitas).json()["patient_data"]
l1 = [ { cf["controlled_food"]: cf["increment_auc"] for cf in tolerance["tolerance_curve_measure"] } for tolerance in datos ]
df1 = pd.json_normalize(datos)
df1.drop("tolerance_curve_measure", inplace=True, axis=1)
df1.drop('sample.time_sample_was_taken', inplace=True, axis=1)
df1.rename(columns= lambda x: x.split(".")[1] if "." in x else x, inplace=True)
return pd.concat([df1, pd.DataFrame(l1)], axis=1)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment