Cheyne-Stoke Respiration


One can create art with data, many have proven that with beautiful infographics or dazzling company reports. I thought using R to create an artistic rendering of a normally mundane process would be neat. I developed a graphic based on Cheyne-Stokes respiration using ggplot. Code is included at the end.

Cheyne-Stokes respiration graphic

One can create art with data, many have proven that with beautiful infographics or dazzling company reports. I thought using R to create an artistic rendering of a normally mundane process would be neat. I developed a graphic based on Cheyne-Stokes respiration using ggplot.

I think the resulting work (right) has a sci-fi feel to it (think Galactic Empire from Star Wars), almost like it could be a symbol for a corporation should the sinusoidal lobes be made solid. Below I have included the full code needed to replicate the graph, most of it is automatic after specifying a couple of parameters. This was the main advantage of coding the design over manually creating it, I could iterate quickly until I found a look that I agreed with sans wasting a lot of time doing fine adjustments.

I won't go over the code in detail as it is largely self-explanatory (though pardon an inefficient techniques, this was a five minute job completed during a meeting). Basically I use a mirror set of times centered around zero to create a smooth, enveloped sine wave (hyperpnoea) and include bouts of no breathing (aponea). The bars to signify hyperpnoea/aponea are just modified error bars and the entire image is made more salient by shifting the coordinates to polar.

Note: The code isn't fancy (made during a meeting), so pardon the lack of efficiency or beauty at parts. The black line is the breathing rate while the red and blue interlocking lines signify aponea and hyperpnoea, respectively.

R / S+
  1. # biafra ahanonu
  2. # updated: 2013.04.12
  3. # short script to make an artistic rendering of cheyne-stokes respiration
  4. #________________________________________________________
  5. # Load libraries and dependencies
  6. # For plotting
  7. library(ggplot2)
  8. # Add time-stamped footnote to graphs
  9. source("view.footnote.R")
  10. #________________________________________________________
  11. # amplitude of breathing, script auto-adjust parameters to this
  12. breathing.amplitude = 42;
  13. # set the frequency of the resulting curve
  14. heartFreq = 1+100/(1+.001*exp(breathing.amplitude))
  15. # make a forward and back hyperpnoea, to make an envelope sinusoid
  16. hyperpnoea.seq=seq(-breathing.amplitude,breathing.amplitude,.1);
  17. aponea.seq=rep(breathing.amplitude, .5*length(hyperpnoea.seq));
  18. # state number of cycles to repeat hyperpnoea and aponea
  19. cycles = 4;
  20. time=rep(c(aponea.seq,hyperpnoea.seq),cycles);
  21. # length of hyperpnoea/aponea cycle
  22. len.cycle = length(c(aponea.seq,hyperpnoea.seq));
  23. # add noise to the signal of desired
  24. noise = 0; #runif(length(time),1,breathing.amplitude^2);
  25. # make a dataframe of the value and times
  26. heart = data.frame(value=sin(heartFreq*time)*(-time^2+time+breathing.amplitude^2)+breathing.amplitude+noise,time=c(0:(length(time)-1)));
  27. # create data.frames containing location of hyperpnoea/aponea lines
  28. minC = seq(0,cycles-1,1)*len.cycle;
  29. maxC = seq(0,cycles-1,1)*len.cycle+length(aponea.seq);
  30. aponea = data.frame(min=minC,max=maxC,y=(breathing.amplitude^2)/2,x=1,id="aponea");
  31. hyperpnoea = data.frame(min=minC+length(aponea.seq),max=maxC+length(hyperpnoea.seq),y=(breathing.amplitude^2)/1.5,x=1,id="hyperpnoea");
  32. bardata = rbind(aponea,hyperpnoea);
  33. # set bar height
  34. bH = (breathing.amplitude^2)/4;
  35. # ggplot of heart respiration
  36. # I have not included by graphing wrapper function for simplicity'hyperpnoea.seq sake
  37. stokesPlot = ggplot(heart,aes(time,value))+
  38. geom_line()+
  39. # add hyperpnoea/aponea bars
  40. geom_errorbarh(mapping=aes(xmin=min,xmax=max,y=y,x=x,colour=id,height=bH),data=bardata, inherit.aes=FALSE)+
  41. ylab('depth of respiration')+
  42. xlab('time (hyperpnoea.seq)')+
  43. ggtitle('Cheyne–Stokes respiration')+
  44. # theme_set(theme_grey(base_size = 25))+
  45. theme(axis.text.x = element_text(angle=90,hjust=1,vjust=.5,color="white"),panel.background=element_rect(fill="white",colour="white"))+
  46. theme(panel.grid = element_line(linetype="2925"))+
  47. theme(axis.text = element_text(color="white"),axis.ticks = element_line(color="white"))+
  48. coord_polar()
  49. print(stokesPlot)
  50. # save a copy of the chart to the current directory
  51. png(paste("cheyne_stoke_art.png",sep=""),width=2400,height=1350,res=400,pointsize=1,antialias = "cleartype")
  52.         print(stokesPlot)
  53.         makeFootnote()



comments powered by Disqus

other entires to explore:

29 may 2012 | programming

The new-tab page on most browsers inefficiently uses screen real estate by giving each website a picture and large button. While useful for[...] tablets, it prevents addition of many websites and can't be organized into groups without increasing the number of clicks required. Also, often only one search site is accessible, with the rest found in a drop-down menu. To alleviate this, I created quicklinks. It uses javascript to create a row of categories (that you choose), which when hovered over show associated links. Further, there are several search bars readily avaliable, no extra clicking needed. Enjoy.

social chair spring 2012
27 december 2011 | psk

My terms as social chair during Fall 2011 went quite well, but there were several things I was unsatisfied with. This presentation outlines[...] several different areas I would like to see improved.

filugori reboot
15 may 2012 | filugori

Several months ago I took a hard look at Filugori: The Long Tale, the story I started in grade school that was meant to be a mash-[...]up of my favorite books and fictional universes. However, it lacked a certain vision. The story was fun, frantic and fanciful, but there was no heart. It lacked cohesion and the universe did not appear to justify its own existence. Why should someone care to read this tale? What would they gain from it? While fleshing out the background of the universe, providing details on the four major epochs that define the story, I came to realize that I wanted to tell a very different tale than originally planned.

bio42: diagrams, part 1
25 january 2013 | teaching

Had a couple minutes to spare before leaving lab, so decided to throw together some diagrams to help explain a couple biological pathways s[...]tudents of bio42, a bio class at Stanford I'm TAing. Hoping to make a set for each system we study. Started with vesicle budding and fusion along with muscle contraction in smooth and skeletal muscles.

©2006-2017 | biafra ahanonu | updated 19 june 2017
biafra ahanonu