Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions transplant/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,29 @@
'Tabagisme_donor', 'Aspirations_donor', 'RX_donor', 'PF_donor',
'oto_score']
}


TRESHOLD_JSON_TS = {'Temp': {'etendue': [0, 50], 'normalite': [0, 50]},
'B.I.S': {'etendue': [0, 100], 'normalite': [0, 100]},
'BIS SR': {'etendue': [0, 100], 'normalite': [0, 100]},
'ETCO2': {'etendue': [0, 120], 'normalite': [0, 120]},
'FiO2': {'etendue': [21, 100], 'normalite': [21, 100]},
'FR': {'etendue': [0, 60], 'normalite': [0, 60]},
'PEEPtotal': {'etendue': [0, 20], 'normalite': [0, 20]},
'Pmax': {'etendue': [0, 65], 'normalite': [0, 65]},
'Pmean': {'etendue': [0, 40], 'normalite': [0, 40]},
'SpO2': {'etendue': [0, 100], 'normalite': [0, 100]},
'SvO2 (m)': {'etendue': [0, 100], 'normalite': [0, 100]},
'VT': {'etendue': [0, 900], 'normalite': [0, 900]},
'DC': {'etendue': [0, 5, 10], 'normalite': [0, 5, 10]},
'FC': {'etendue': [0, 220], 'normalite': [0, 220]},
'PAPdia': {'etendue': [0, 65], 'normalite': [0, 65]},
'PAPmoy': {'etendue': [0, 65], 'normalite': [0, 65]},
'PAPsys': {'etendue': [0, 120], 'normalite': [0, 120]},
'PASd': {'etendue': [0, 80], 'normalite': [0, 80]},
'PASm': {'etendue': [0, 150], 'normalite': [0, 150]},
'PASs': {'etendue': [0, 320], 'normalite': [0, 320]},
'PNId': {'etendue': [0, 80], 'normalite': [0, 80]},
'PNIm': {'etendue': [0, 150], 'normalite': [0, 150]},
'PNIs': {'etendue': [0, 320], 'normalite': [0, 320]}
}
38 changes: 38 additions & 0 deletions transplant/features/dynamic_features.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pandas as pd
import json
import os
import pandas as pd
import seaborn as sns
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A ajouter au fichier requirements.txt pour être bien sûr qu'on ait toutes les libs au setup!

import numpy as np
import matplotlib.pyplot as plt
from transplant.config import (TRESHOLD_JSON_TS)


class time_serie_fX:
"""
Compute features on TS for the dynamic dataset
Input :
- df [pandasdataframe]: dynamic Dataset
Output :
- df [pandas dataframe], with new features (with prefix)

"""

def __init__(self, df):
self.df = df

def treshold_fX(self, treshold_json=TRESHOLD_JSON_TS):

for i in treshold_json.keys():

tjson = treshold_json[i]
name_new_feature = i
serie = self.df[i]
cond1 = ((serie >= tjson["etendue"][0]) & (serie < tjson["normalite"][0]))

cond2 = (serie <= tjson["etendue"][1]) & (serie > tjson["normalite"][1])

self.df[i + "_abnormal_treshFx"] = np.where(cond1 | cond2, 1, 0)

self.df[i + "_clean_treshFx"] = np.where((serie >= tjson["etendue"][0])
& (serie <= tjson["etendue"][1]), 1, 0)
1 change: 1 addition & 0 deletions transplant/visualization/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .graph import plot_dynamic_features, plot_compare_patient, plot_tresh
141 changes: 91 additions & 50 deletions transplant/visualization/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,72 @@

import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot

import matplotlib.pyplot as plt


def plot_dynamic_features(df, id_patient, features_list):
"""
Plot a dynamic graph of patient from medical measuring instrument.
Work only in notebook.
Display only numerical features
Input :

Input :
- df [DataFrame] : Muse have features [['id_patient', 'time']]
- id_patient [int] : Id patient
- features_list [list] : list of features you want to analyse
Ouput :

Ouput :
- Display a plotly graph
"""

init_notebook_mode(connected=True)

# Check params

if not isinstance(features_list, list):
raise Exception("""'features_list' must be a list. \n Example features_list=['FC', 'FIN2O']
raise Exception("""'features_list' must be a list. \n Example features_list=['FC', 'FIN2O']
ou \n features_list=DYNAMIC_CATEGORIES['neurology'])""")

if not isinstance(id_patient, int):
raise Exception("""'id_patient' must be a int. \n Example id_patient=314""")

data = df[df['id_patient'] == id_patient]
if len(data) ==0:

if len(data) == 0:
raise Exception("""No data for this id_patient""")



try:
time = data['time']
except:
raise Exception("""DataFrame need to have time feature ('time')""")

if len(features_list) != 0:

# Init list of trace
data_graph = []

# Remove nonusefull features
features_list = [feature for feature in features_list if feature not in(['time', 'id_patient'])]

# Take only numerical features
features_list_clean = []
for feature in features_list:
if is_numeric_dtype(df[feature]):
features_list_clean.append(feature)

if len(features_list_clean) == 0:
raise Exception("""No numeric data is this DataFrame""")

# Create trace for data_graph
for feature in features_list_clean:
trace = go.Scatter(x=time,
y=data[feature].values,
name = feature,
yaxis='y1')
data_graph.append(trace)
data_graph.append(trace)
else:
raise Exception("""No data for this id_patient""")

# Design graph
layout = dict(
title='Analyse du patient ' + str(id_patient),
Expand All @@ -88,51 +87,52 @@ def plot_dynamic_features(df, id_patient, features_list):
fig = dict(data=data_graph, layout=layout)
iplot(fig)


def plot_compare_patient(df, feature_to_analyse, patient_list):
"""
Plot a dynamic graph to compare patient on One feature
Work only in notebook.
Display only numerical features
Input :

Input :
- df [DataFrame] : Muse have features [['id_patient']]
- feature_to_analyse [string] : Name of numerical feature
- patient_list [list] : list of patient you want to compare
Ouput :

Ouput :
- Display a plotly graph
"""

init_notebook_mode(connected=True)

# Check params

if not isinstance(feature_to_analyse, str):
raise Exception("""feature_to_analyse muse be a string - Example 'ETCO2' """)

if feature_to_analyse not in df.columns:
raise Exception("""feature_to_analyse is not in the DataFrame""")

if not is_numeric_dtype(df[feature_to_analyse]):
raise Exception("""feature_to_analyse must be numeric""")

if not isinstance(patient_list, list):
raise Exception("""'patient_list' must be a list - Example [304, 305, 405]""")


data = df[df['id_patient'].isin(patient_list)]

if len(data) ==0:
raise Exception("""No data for these patients""")

# Init list of trace
data_graph = []

for patient in patient_list:
data_temp = data[data['id_patient'] == patient].copy()
if len(data_temp) == 0:
pass

trace = go.Scatter(x=data_temp.reset_index(drop=True).index,
y=data_temp[feature_to_analyse].values,
name = str(patient),
Expand All @@ -154,26 +154,27 @@ def plot_compare_patient(df, feature_to_analyse, patient_list):
fig = dict(data=data_graph, layout=layout)
iplot(fig)


def plot_analyse_factory(df, pca, hue=False, kmean=None):
"""
Plotting result from tools.analyse_factory.analyse_factory()

Input :
Input :
- df [DataFrame] : Muse have features [['id_patient']]
- pca [sklearn.decomposition.PCA] : PCA already fit
- hue [Bool] : Using cluster to plot differents colors
- kmean [sklearn.kmean] : Kmean already fit. hue must be True
Ouput :

Ouput :
- Display a plotly graph
"""

init_notebook_mode(connected=True)

color_list = ['#6ac1a5', '#fa8d67', '#8ea1c9']

pca_expl = round(pca.explained_variance_ratio_[0:2].sum(), 2)

if hue == False:
# Create a trace
trace = go.Scatter(
Expand All @@ -195,23 +196,23 @@ def plot_analyse_factory(df, pca, hue=False, kmean=None):
name = 'cluster_'+str(cluster),
text=df_temp["id_patient"].tolist()
)
data.append(trace)
data.append(trace)

if kmean:

centroids = kmean.cluster_centers_
center = go.Scatter(x=centroids[:, 0],
y=centroids[:, 1],
showlegend=False,
mode='markers',
mode='markers',
text='centroid',
marker=dict(
size=10,
opacity = 0.4,
symbol=17,
color='black'))
data.append(center)

# Design graph
layout = dict(
title='Analyse de feature PCA explain (first 2 components) : ' + str(pca_expl),
Expand All @@ -224,6 +225,46 @@ def plot_analyse_factory(df, pca, hue=False, kmean=None):
title='pca_2'
)
)

fig = dict(data=data, layout=layout)
iplot(fig)
iplot(fig)


def plot_tresh(df, treshold_json, id_patient=100, var="Pmean", title=''):

"""
Plotting time serie with treshold

Input :
- df [DataFrame] : Muse have features [['id_patient']]
- treshold_json [Json]: : must have the following structure
{[colum_name]:
{"etendue": [value_max, value_min],
"normalite" : [val]
}
}
- id_patient [int,str] : patient time serie to plot
- var [str] : serie to plot
- title [str]: title for the chart

Ouput :
- Display a matplotlib graph
"""

serie = df[df.id_patient == id_patient][var]

y = serie.values
x = serie.reset_index().index

fig, ax, = plt.subplots(1, 1, sharex=True)
ax.plot(x, y, color='black')

cond1 = (y <= treshold_json[var]["normalite"][0])
cond2 = (y >= treshold_json[var]["normalite"][1])

ax.fill_between(x, y, treshold_json[var]["normalite"][0], where=cond1,
facecolor='red', interpolate=True)
ax.fill_between(x, y, treshold_json[var]["normalite"][1], where=cond2,
facecolor='red', interpolate=True)
ax.set_title(title)
plt.show()