Visualising vital signs in Dash with Python

From tables to interactive graphs

Kelvin Kramp
Towards Data Science

--

Photo by Matteo Fusco on Unsplash

I vividly remember the graphs of the vital signs of patients during my working period as an MD in the IC department. Graphical representations of vital signs can help in getting a better insight into what is happening behind the curtains. The graphs usually gave far more insight into the health state of a patient than the snapshots of vital signs in other work environments.

Dash is a python module that is getting an increasing amount of attention. With <100 lines of code you can make remarkable beautiful and interactive charts. Dash creates a local server on your computer and the application you build can be accessed via your browser. By doing so you have a graphical user interface (GUI) that you can interact with within your browser. This saves you time in writing a whole user interface to control the functionality of a script or software package. Dash also has a steep learning curve, understanding how to get things done doesn’t take much time. Dash seems to be the perfect python package for data visualisations.

Let’s see if we can create a graphical user interface of the vital signs of a dummy patient. The workflow to achieve this is a three-step process. You get the data, clean the data, and then show the bling bling. The last one is the easiest thanks to Dash, the middle one is the hardest. The full code is on my Github.

We get the data from our dummy patient with a selenium module for web automation and create a dataframe with pandas:

The result should look something like this:

CLEANING

Garbage in, garbage out. So there are a couple of important things here:

  • There are N.A. values in the blood pressure measurements that we cant use in our graph (e.g. — / -).
  • There is text within the blood pressure measurements (e.g. r.a. = right arm).
  • There are deviations from normal (saturation of 20 and breathing frequency of 95 were switched in the 5th row (index 4)). `
  • There are typos: 372.0 should have been 37.2, the problem was that there was a comma used instead of a dot during the input in the patient file. Furthermore, 7.4 in row 6 (index 5) is probably representative of 37.4.

We solve (1) and (2) with the following line of code that uses regex. For more info about regex see the tutorial of Corey Schafer:

The only thing left to do for the blood pressure column is to make two separate columns, one for diastolic and one for systolic blood pressures so we can process them in our graph:

The table will look something like this if you print it. You can see that there are two new columns at the end that show only numerical values:

Point 3 en 4, the removal of outliers, can be achieved with masks and using some reasonable values as filters.

You could also think about using a mathematically more complex filter, such as the Savitzky-Golay filter, to smooth data but in our case, this is not what we want: the abnormalities in the data are often alarm signs, not noise.

VISUALISATION

We create a graph object with the visualisation package plotly:

To display our vital signs in a figure in Dash we need to install some packages:

  • pip install dash
  • pip install dash-core-components
  • pip install dash-html-components

We make a graph by using the dash core component “Graph” to plot the figure. To do this we provide the graph object from the previous section as a variable for the figure:

The result is the graph beneath. Now, let's imagine the patient received metoprolol (blood pressure medication) on the 7th of February, we can now see in the graph that there was a decrease in systolic blood pressure on the 8th of February and also a decrease in pulse from around 90 to 70 bpm so it then looks like the intervention worked:

A lot of calls during on-call shifts are focused on the question of whether to isolate or not isolate a patient based on a specific temperature. If you unselect all vital signs on the right and only leave the temperature in the list you get more insight into the temperatures variation through time. It becomes easy to identify a subfebrile temperature (=37.5–38.4) on 4 February. It seemed to likely be a consequence of the normal circadian rhythm (biological variability) or an error measurement (measurement variability) because in follow-up measurements the temperature was within the normal range. A visualisation like this can make making decisions around covid related consultations easier.

That was a quick and easy data visualisation of vital signs. This is of course all just an example. There is a lot more to do before something like this is usable in a day-to-day work environment but I hope I have shown you that the brothers, Python and Dash, are two good candidates for future work…

--

--