Adult Decompensation ICU Subcohort Sankey Diagram

Author: Ziyuan Shen

Last Revision: 11/03/2019

The notebook refers sankey diagram of CTICU project. The author thanks Shujin Zhong for coding support.

Load Data

Patient flow data are generated from inside PACE.

In [1]:
import pandas as pd
import numpy as np
import plotly
from IPython.core.display import HTML
plotly.offline.init_notebook_mode()

Source = [14, 14, 14, 14, 12, 12, 0,  0, 20, 20, 29, 29,  2,  2,  2,  2,  2, 7, 7, 3, 3, 16, 16, 33, 33, 33, 33, 
           33, 33, 1, 28, 28, 28, 17, 11, 11, 11,  6,  6, 6, 24, 24, 24, 13, 13, 13, 13, 30, 9, 32, 15, 23, 23, 
           8, 8, 10, 27, 26, 21, 22, 5, 4, 18, 19, 25, 25, 25, 25, 25]

Target = [2, 7, 3, 16, 7, 16, 2, 16, 2, 16, 2, 3, 28, 17, 11, 6, 31, 33, 6, 33, 6, 33, 1, 30, 9, 32, 15, 8, 31, 
          32, 13, 23, 31, 31, 13, 8, 31, 24, 13, 9, 26, 21, 22, 26, 21, 22, 31, 31, 31, 31, 31, 10, 26, 10, 22, 
          4, 31, 31, 31, 31, 31, 31, 31, 31, 14, 12, 0, 20, 29]

Value = [7640, 2734, 1146, 696, 325, 609, 1157, 1567, 352, 3939, 4392, 325, 6483, 670, 4147, 805, 1097, 2030, 
         825, 827, 542, 5796, 607, 403, 1706, 1127, 3443, 318, 1460, 257, 283, 279, 5871, 515, 237, 248, 
         3431, 904, 890, 202, 345, 217, 302, 207, 452, 219, 323, 500, 1569, 1156, 3134, 330, 200, 331, 229, 
         206, 232, 687, 533, 685, 221, 245, 279, 305, 12216, 1119, 2767, 4333,4855]

name_numb = {'1-floor_1': 0, '3-ICU_2': 1, '2-ICU_1': 2, '2-stepdown_1': 3, '6-stepdown_1': 4, 
             '6-floor_3': 5, '3-surgery_1': 6, '2-floor_1': 7, '4-surgery_2': 8, '4-floor_2': 9, 
             '5-ICU_2': 10, '3-stepdown_1': 11, '1-ICU_1': 12, '4-ICU_2': 13, '1-ED_1': 14, 
             '4-stepdown_2': 15, '2-surgery_1': 16, '3-floor_2': 17, '6-stepdown_2': 18, 
             '6-stepdown_3': 19, '1-stepdown_1': 20, '5-stepdown_1': 21, '5-stepdown_2': 22, 
             '4-surgery_1': 23, '4-ICU_1': 24, 'Admission': 25, '5-floor_2': 26, '5-floor_1': 27, 
             '3-floor_1': 28, '1-surgery_1': 29, '4-floor_1': 30, 'Discharge': 31, '4-stepdown_1': 32, 
             '3-ICU_1': 33}

test = pd.DataFrame({'From': Source, 'To': Target, 'Values': Value})
color_dic = {'Admission': 'rgba(239, 239, 129, 1)', # yellow
             'ED': 'rgba(117, 164, 250, 1)', # blue
             'floor': 'rgba(123, 201, 108, 1)', # green
             'stepdown': 'rgba(247, 163, 80, 1)', # orange
             'surgery': 'rgba(219, 102, 255, 1)', # purple
             'ICU': 'rgba(252, 64, 64, 1)', # red
             'Discharge': 'rgba(69, 56, 253, 1)' # dark blue
            }

def css_styling():
    styles = """<style>
                .foo {
                  text-align: left;
                  width: 20px;
                  height: 20px;
                  margin: 5px;
                  border: 0px solid rgba(0, 0, 0, .2);
                  }
                .yellow {background: #EFEF81;}
                .blue {background: #75A4FA;}
                .green {background: #7BC96C;}
                .orange {background: #F7A350;}
                .purple {background: #DB66FF;}
                .red {background: #FC4040;}
                .dark-blue {background: #4538FD;}
                </style>
             """
    return HTML(styles)

def find_unit_color(unit):
    for key in color_dic.keys():
        if key in unit:
            return color_dic[key]

cn = list(map(find_unit_color, name_numb.keys()))
cl = list(map(lambda x: x.replace('1)', '0.5)'), cn))
cn = np.array(cn)
cl = np.array(cl)

test['Colors'] = cl[test['From'].values.astype(int)]

data_trace = dict(
    type='sankey',
    arrangement = "freeform",
    domain = dict(
      x =  [0,1],
      y =  [0,1]
    ),
    orientation = "h",
    valueformat = ".0f",
    
    node = dict(
      pad = 5,
      thickness = 5,
      label =  list(name_numb),
      color =  cn
    ),
    link = dict(
      source = test['From'],
      target = test['To'],
      value = test['Values'],
      color = test['Colors'],
  ))
layout =  dict(
    title = "Adult Decompensation ICU Subcohort Patient Flow",
    titlefont = dict(size = 20),
    font = dict(size = 10)
)
css_styling()
Out[1]:

Create Visualization

Visualization Goal

Identify from which units patients come before each ICU admission, and to which units patients go after each ICU stay.

Visualization Specifics

  • subcohort: all encounters which touch ICU (within adult decompensation cohort)
  • number of encounters: 25290
  • each encounter flow is generated from hospital Admssion to Discharge
  • lower boundary of stay in each category of unit: 30 minutes
  • lower boundary of the number of each distinct type of transfer: 200
  • all hospital departments (including Admission and Discharge here) are categorized as:
          Admission
          ED (Emergency Department)
          floor
          stepdown
          surgery (stepdown)
          ICU (Intensive Care Unit)
          Discharge
  • each node in sankey diagram is named by the unit category with a prefix i- denoting it's the ith transfer within each encounter, and a suffix _j denoting it's the jth time the patient enters the same unit category during the encounter
In [2]:
fig = dict(data=[data_trace], layout=layout)
plotly.offline.iplot(fig, validate=False)
In [ ]: