eICU Collaborative Research Database

Notebook 3: Plot timeseries data for a single patient stay

The aim of this notebook is to create a series of plots using timeseries data available for a single patient stay, using the following tables:

  • patient
  • vitalperiodic
  • vitalaperiodic
  • lab

Before starting, you will need to install a copy the eICU Collaborative Research Database. For instructions on installing the database, see: .

Documentation on the eICU Collaborative Research Database can be found at: http://eicu-crd.mit.edu/.

1. Getting set up


In [ ]:
# Import libraries
import pandas as pd
import matplotlib.pyplot as plt
import psycopg2
import os

In [ ]:
# Plot settings
%matplotlib inline
plt.style.use('ggplot')
fontsize = 20 # size for x and y ticks
plt.rcParams['legend.fontsize'] = fontsize
plt.rcParams.update({'font.size': fontsize})

In [ ]:
# Connect to the database - which is assumed to be in the current directory
fn = 'eicu_demo.sqlite3'
con = sqlite3.connect(fn)
cur = con.cursor()

2. Display a list of tables


In [ ]:
query = \
"""
SELECT type, name
FROM sqlite_master 
WHERE type='table'
ORDER BY name;
"""

list_of_tables = pd.read_sql_query(query,con)

In [ ]:
list_of_tables

3. Selecting a single patient stay

3.1. The patient table

The patient table includes general information about the patient admissions (for example, demographics, admission and discharge details). See: http://eicu-crd.mit.edu/eicutables/patient/


In [ ]:
# select a single ICU stay
patientunitstayid = 141296

In [ ]:
# query to load data from the patient table
query = \
"""
SELECT *
FROM patient
WHERE patientunitstayid = {}
""".format(patientunitstayid)

print(query)

In [ ]:
# run the query and assign the output to a variable
unitstay = pd.read_sql_query(query,con)

In [ ]:
# display the first few rows of the dataframe
unitstay.head()

3.2. The vitalperiodic table

The vitalperiodic table comprises data that is consistently interfaced from bedside vital signs monitors into eCareManager. Data are generally interfaced as 1 minute averages, and archived into the vitalperiodic table as 5 minute median values. For more detail, see: http://eicu-crd.mit.edu/eicutables/vitalPeriodic/


In [ ]:
# query to load data from the patient table
query = \
"""
SELECT *
FROM vitalperiodic
WHERE patientunitstayid = {}
""".format(patientunitstayid)

print(query)

In [ ]:
# run the query and assign the output to a variable
vitalperiodic = pd.read_sql_query(query,con)

In [ ]:
# display the first few rows of the dataframe
vitalperiodic.head()

In [ ]:
# display a full list of columns
vitalperiodic.columns

In [ ]:
# sort the values by the observationoffset (time in minutes from ICU admission)
vitalperiodic = vitalperiodic.sort_values(by='observationoffset')
vitalperiodic.head()

In [ ]:
# subselect the variable columns
columns = ['observationoffset','temperature','sao2','heartrate','respiration',
          'cvp','etco2','systemicsystolic','systemicdiastolic','systemicmean',
          'pasystolic','padiastolic','pamean','st1','st2','st3','icp']

vitalperiodic = vitalperiodic[columns].set_index('observationoffset')
vitalperiodic.head()

In [ ]:
# plot the data
figsize = (18,8)
title = 'Vital signs (periodic) for patientunitstayid = {} \n'.format(patientunitstayid)
ax = vitalperiodic.plot(title=title, figsize=figsize, fontsize=fontsize,
                       marker='o')

ax.title.set_size(fontsize)
ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
ax.set_xlabel("Minutes after admission to the ICU")
ax.set_ylabel("Absolute value")

Questions

  • Which variables are available for this patient?
  • What is the peak heart rate during the period?

3.3. The vitalaperiodic table

The vitalAperiodic table provides invasive vital sign data that is recorded at irregular intervals. See: http://eicu-crd.mit.edu/eicutables/vitalAperiodic/


In [ ]:
# query to load data from the patient table
query = \
"""
SELECT *
FROM vitalaperiodic
WHERE patientunitstayid = {}
""".format(patientunitstayid)

print(query)

In [ ]:
# run the query and assign the output to a variable
vitalaperiodic = pd.read_sql_query(query,con)

In [ ]:
# display the first few rows of the dataframe
vitalaperiodic.head()

In [ ]:
vitalaperiodic.columns

In [ ]:
# sort the values by the observationoffset (time in minutes from ICU admission)
vitalaperiodic = vitalaperiodic.sort_values(by='observationoffset')
vitalaperiodic.head()

In [ ]:
# subselect the variable columns
columns = ['observationoffset','noninvasivesystolic','noninvasivediastolic',
          'noninvasivemean','paop','cardiacoutput','cardiacinput','svr',
          'svri','pvr','pvri']

vitalaperiodic = vitalaperiodic[columns].set_index('observationoffset')
vitalaperiodic.head()

In [ ]:
# plot the data
figsize = (18,8)
title = 'Vital signs (aperiodic) for patientunitstayid = {} \n'.format(patientunitstayid)
ax = vitalaperiodic.plot(title=title, figsize=figsize, fontsize=fontsize,
                        marker='o')

ax.title.set_size(fontsize)
ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
ax.set_xlabel("Minutes after admission to the ICU")
ax.set_ylabel("Absolute value")

Questions

  • What do the non-invasive variables measure?
  • How do you think the mean is calculated?

3.4. The lab table


In [ ]:
# query to load data from the patient table
query = \
"""
SELECT *
FROM lab
WHERE patientunitstayid = {}
""".format(patientunitstayid)

print(query)

In [ ]:
# run the query and assign the output to a variable
lab = pd.read_sql_query(query,con)

In [ ]:
# display the first few rows of the dataframe
lab.head()

In [ ]:
# list columns in the table
lab.columns

In [ ]:
# sort the values by the offset time (time in minutes from ICU admission)
lab = lab.sort_values(by='labresultoffset')
lab.head()

In [ ]:
# set the index to the offset time
lab = lab.set_index('labresultoffset')
lab.head()

In [ ]:
# subselect the variable columns
columns = ['labname','labresult','labmeasurenamesystem']
lab = lab[columns]
lab.head()

In [ ]:
# list the distinct labnames
lab['labname'].unique()

In [ ]:
# pivot the lab table to put variables into columns
lab = lab.pivot(columns='labname', values='labresult')
lab.head()

In [ ]:
# plot laboratory tests of interest
labs_to_plot = ['creatinine','pH','Hgb', 'total bilirubin', 
                'potassium', 'Tacrolimus-FK506', 'WBC x 1000']
lab[labs_to_plot].head()

In [ ]:
# plot the data
figsize = (18,8)
title = 'Laboratory test results for patientunitstayid = {} \n'.format(patientunitstayid)
ax = lab[labs_to_plot].plot(title=title, figsize=figsize, fontsize=fontsize, marker='o',ms=10, lw=0)

ax.title.set_size(fontsize)
ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
ax.set_xlabel("Minutes after admission to the ICU")
ax.set_ylabel("Absolute value")