{"id":1406,"date":"2012-12-19T20:36:33","date_gmt":"2012-12-20T01:36:33","guid":{"rendered":"http:\/\/lukemiller.org\/?p=1406"},"modified":"2012-12-23T14:01:29","modified_gmt":"2012-12-23T19:01:29","slug":"generating-polygon-boundaries-for-plotting-simple-time-series-data-with-missing-data","status":"publish","type":"post","link":"https:\/\/lukemiller.org\/index.php\/2012\/12\/generating-polygon-boundaries-for-plotting-simple-time-series-data-with-missing-data\/","title":{"rendered":"Generating polygon boundaries for plotting simple time series data with missing data"},"content":{"rendered":"<p>Every so often I want to plot some data with pretty upper and lower error bounds, such as temperature data through time, perhaps with the maximum and minimum temperature range or standard error bounds for averaged data. The polygon( ) function can make those sorts of pretty plots. However, I&#8217;ll often have chunks of missing data for periods of time, so I have to break up the polygons that go with the plotted data. I could swear I wrote a function to do this several months ago, but it&#8217;s lost in a pile of other scripts, so I re-wrote a function to accomplish the task.<\/p>\n<figure id=\"attachment_1407\" aria-describedby=\"caption-attachment-1407\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/12\/ex_fig.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1407\" alt=\"A simple example, where the purple\/blue polygon might represent the range around the mean value through time.\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/12\/ex_fig.png\" width=\"300\" height=\"300\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/12\/ex_fig.png 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/12\/ex_fig-150x150.png 150w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1407\" class=\"wp-caption-text\">A simple example, where the purple\/blue polygon might represent the range around the mean value through time.<\/figcaption><\/figure>\n<p>The plot above shows the kind of thing I&#8217;m talking about. I might have a series of times, or dates, or just random x data, and associated y values (a mean, and upper and lower bounds around the mean). But somewhere in the data set the y-values are missing. The goal is to simplify the process of generating the x-y pair values needed for polygon( ) to plot the error values, and automatically deal with any breaks in the data set.<\/p>\n<p>The R script to generate the function polylims( ) is <a href=\"https:\/\/github.com\/millerlp\/Misc_R_scripts\/blob\/master\/polylims.R\" target=\"_blank\">hosted on GitHub.<\/a> The function should handle datasets with any number of missing chunks, but it will also work equally well on datasets without missing points. John McKinlay pointed me to the rle( ) function shortly after I originally posted this, and it helps shrink the amount of code considerably. The modified code is shown below:<\/p>\n<div style=\"overflow: auto;\">\n<div class=\"geshifilter\">\n<pre class=\"r geshifilter-R\" style=\"font-family: monospace;\">polylims = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/function\"><span style=\"color: #003399; font-weight: bold;\">function<\/span><\/a><span style=\"color: #009900;\">(<\/span>xdata<span style=\"color: #339933;\">,<\/span> ydata<span style=\"color: #339933;\">,<\/span> ydata2<span style=\"color: #009900;\">)<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># A function to find the beginings and endings of each run of real numbers<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># in a set of data, in order to create polygons for plotting. The assumption<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># is that ydata, ydata2, and xdata vectors are the same length, and that <\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># the ydata and ydata2 vectors contain NA values for missing data. The <\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># same values in ydata and ydata2 must be missing. The output will be <\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># a list of data frames of x and y values suitable for plotting polygons.<\/span>\r\n\r\n\t<span style=\"color: #666666; font-style: italic;\"># Use rle function to find contiguous real numbers<\/span>\r\n\trl = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/rle\"><span style=\"color: #003399; font-weight: bold;\">rle<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/is.na\"><span style=\"color: #003399; font-weight: bold;\">is.na<\/span><\/a><span style=\"color: #009900;\">(<\/span>ydata<span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span>\r\n\tstarts = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/vector\"><span style=\"color: #003399; font-weight: bold;\">vector<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span>\r\n\tends = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/vector\"><span style=\"color: #003399; font-weight: bold;\">vector<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span>\r\n\tindx = <span style=\"color: #cc66cc;\">1<\/span>\r\n\t<span style=\"color: #000000; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">1<\/span><span>:<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/length\"><span style=\"color: #003399; font-weight: bold;\">length<\/span><\/a><span style=\"color: #009900;\">(<\/span>rl<span>$<\/span>lengths<span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">{<\/span>\r\n\t\t<span style=\"color: #000000; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">(<\/span>rl<span>$<\/span>values<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># Value was NA, advance index without saving the numeric values<\/span>\r\n\t\t\tindx = indx <span>+<\/span> rl<span>$<\/span>lengths<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span> <span style=\"color: #000000; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">{<\/span>\r\n\t\t\t<span style=\"color: #666666; font-style: italic;\"># Value was a real number, extract and save those values<\/span>\r\n\t\t\tstarts = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span>starts<span style=\"color: #339933;\">,<\/span>indx<span style=\"color: #009900;\">)<\/span>\r\n\t\t\tends = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span>ends<span style=\"color: #339933;\">,<\/span> <span style=\"color: #009900;\">(<\/span>indx <span>+<\/span> rl<span>$<\/span>lengths<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span> <span>-<\/span> <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\t\tindx = indx <span>+<\/span> rl<span>$<\/span>lengths<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span>\r\n\t\t<span style=\"color: #009900;\">}<\/span>\t\r\n\t<span style=\"color: #009900;\">}<\/span>\r\n\r\n\t<span style=\"color: #666666; font-style: italic;\"># At this point the lengths of the vectors 'starts' and 'ends' should be<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># equal, and each pair of values represents the starting and ending indices<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># of a continuous set of data in the ydata vector.<\/span>\r\n\r\n\t<span style=\"color: #666666; font-style: italic;\"># Next separate out each set of continuous ydata, and the associated xdata,<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># and format them for plotting as a polygon.<\/span>\r\n\tpolylist = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/list\"><span style=\"color: #003399; font-weight: bold;\">list<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t<span style=\"color: #000000; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">1<\/span><span>:<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/length\"><span style=\"color: #003399; font-weight: bold;\">length<\/span><\/a><span style=\"color: #009900;\">(<\/span>starts<span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">{<\/span>\r\n\t\ttemp = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/data.frame\"><span style=\"color: #003399; font-weight: bold;\">data.frame<\/span><\/a><span style=\"color: #009900;\">(<\/span>x = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span>xdata<span style=\"color: #009900;\">[<\/span>starts<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span>xdata<span style=\"color: #009900;\">[<\/span>starts<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span>:<\/span>ends<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/rev\"><span style=\"color: #003399; font-weight: bold;\">rev<\/span><\/a><span style=\"color: #009900;\">(<\/span>xdata<span style=\"color: #009900;\">[<\/span>starts<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span>:<\/span>ends<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\ty = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span>ydata<span style=\"color: #009900;\">[<\/span>starts<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span>ydata2<span style=\"color: #009900;\">[<\/span>starts<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span>:<\/span>ends<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\t\t\t\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/rev\"><span style=\"color: #003399; font-weight: bold;\">rev<\/span><\/a><span style=\"color: #009900;\">(<\/span>ydata<span style=\"color: #009900;\">[<\/span>starts<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span>:<\/span>ends<span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span>\r\n\t\tpolylist<span style=\"color: #009900;\">[<\/span><span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span> = temp\t\r\n\t<span style=\"color: #009900;\">}<\/span>\r\n\tpolylist\r\n\t<span style=\"color: #666666; font-style: italic;\"># You can iterate through the items in polylist and plot them as <\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\"># polygons on your plot. Use code similar to the following:<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\">#\tfor (i in 1:length(polylist)){<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\">#\t\t\tpolygon(polylist[[i]]$x, polylist[[i]]$y, <\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\">#\t\t\t\tcol = rgb(0.5,0.5,0.5,0.5), border = NA)<\/span>\r\n\t<span style=\"color: #666666; font-style: italic;\">#\t}<\/span>\r\n<span style=\"color: #009900;\">}<\/span><\/pre>\n<\/div>\n<\/div>\n<p><a title=\"Created by Pretty R at inside-R.org\" href=\"http:\/\/www.inside-r.org\/pretty-r\">Created by Pretty R at inside-R.org<\/a><\/p>\n<p>Run that once, and it creates a function called polylims that you can use in your R session. Below is an example of how I use it. We&#8217;ll start by generating some junk data consisting of a time series of y-values, with upper and lower error bounds. Assemble those into a data frame, and lose some of the data in the middle of the series.<\/p>\n<div style=\"overflow: auto;\">\n<div class=\"geshifilter\">\n<pre class=\"r geshifilter-R\" style=\"font-family: monospace;\"><span style=\"color: #666666; font-style: italic;\"># Create a sequence of time points<\/span>\r\ntimes = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/seq\"><span style=\"color: #003399; font-weight: bold;\">seq<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.POSIXct\"><span style=\"color: #003399; font-weight: bold;\">as.POSIXct<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'2012-12-10 00:00'<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">, <\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/as.POSIXct\"><span style=\"color: #003399; font-weight: bold;\">as.POSIXct<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #0000ff;\">'2012-12-10 12:00'<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> \r\n\t\t<a href=\"http:\/\/inside-r.org\/r-doc\/base\/by\"><span style=\"color: #003399; font-weight: bold;\">by<\/span><\/a> = <span style=\"color: #cc66cc;\">300<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Create some fake y data, one value for each time point<\/span>\r\ny = <a href=\"http:\/\/inside-r.org\/r-doc\/stats\/rnorm\"><span style=\"color: #003399; font-weight: bold;\">rnorm<\/span><\/a><span style=\"color: #009900;\">(<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/length\"><span style=\"color: #003399; font-weight: bold;\">length<\/span><\/a><span style=\"color: #009900;\">(<\/span>times<span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/inside-r.org\/r-doc\/base\/mean\"><span style=\"color: #003399; font-weight: bold;\">mean<\/span><\/a> = <span style=\"color: #cc66cc;\">10<\/span><span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/inside-r.org\/r-doc\/stats\/sd\"><span style=\"color: #003399; font-weight: bold;\">sd<\/span><\/a> = <span style=\"color: #cc66cc;\">0.5<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Create a fake upper standard error limit for each y data point<\/span>\r\nupperse = y <span>+<\/span> <span style=\"color: #cc66cc;\">2<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Create a fake lower standard error limit for each y data point<\/span>\r\nlowerse = y <span>-<\/span> <span style=\"color: #cc66cc;\">2<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Assemble all this into a data frame<\/span>\r\nmydata = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/data.frame\"><span style=\"color: #003399; font-weight: bold;\">data.frame<\/span><\/a><span style=\"color: #009900;\">(<\/span>times<span style=\"color: #339933;\">, <\/span>y<span style=\"color: #339933;\">, <\/span>upperse<span style=\"color: #339933;\">, <\/span>lowerse<span style=\"color: #009900;\">)<\/span>\r\n\r\n<span style=\"color: #666666; font-style: italic;\"># Now we'll \"lose\" some data in the middle of the data set.<\/span>\r\nmydata<span style=\"color: #009900;\">[<\/span><span style=\"color: #cc66cc;\">45<\/span><span>:<\/span><span style=\"color: #cc66cc;\">50<\/span><span style=\"color: #339933;\">,<\/span><span>-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">]<\/span> = <span style=\"color: #000000; font-weight: bold;\">NA<\/span><\/pre>\n<\/div>\n<\/div>\n<p>After doing that, I&#8217;ll call the polylims( ) function, passing it the x data and the upper\/lower error bounds. The original &#8216;y&#8217; data aren&#8217;t needed here, just the upper\/lower bounds.<\/p>\n<div style=\"overflow: auto;\">\n<div class=\"geshifilter\">\n<pre class=\"r geshifilter-R\" style=\"font-family: monospace;\"><span style=\"color: #666666; font-style: italic;\"># Call the polylims function, supplied with x data, and the two sets of y data<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># that represent our upper and lower error boundaries here<\/span>\r\npolys = polylims<span style=\"color: #009900;\">(<\/span>mydata<span>$<\/span>times<span style=\"color: #339933;\">, <\/span>mydata<span>$<\/span>upperse<span style=\"color: #339933;\">, <\/span>mydata<span>$<\/span>lowerse<span style=\"color: #009900;\">)\r\n\r\n<\/span><\/pre>\n<\/div>\n<\/div>\n<p>The output object &#8216;polys&#8217; is a list of data frames, each containing a column x and column y, which hold the x-y pairs needed to plot each polygon. Since there is a break in the example data, &#8216;polys&#8217; contains two such data frames. Continue by plotting the data.<\/p>\n<div style=\"overflow: auto;\">\n<div class=\"geshifilter\">\n<pre class=\"r geshifilter-R\" style=\"font-family: monospace;\"><span style=\"color: #666666; font-style: italic;\"># Draw the basic plot<\/span>\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/graphics\/plot\"><span style=\"color: #003399; font-weight: bold;\">plot<\/span><\/a><span style=\"color: #009900;\">(<\/span>mydata<span>$<\/span>times<span style=\"color: #339933;\">,<\/span> mydata<span>$<\/span>y<span style=\"color: #339933;\">,<\/span> type = <span style=\"color: #0000ff;\">'l'<\/span><span style=\"color: #339933;\">,<\/span> ylim = <a href=\"http:\/\/inside-r.org\/r-doc\/base\/c\"><span style=\"color: #003399; font-weight: bold;\">c<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #cc66cc;\">5<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #cc66cc;\">15<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> xlab = <span style=\"color: #0000ff;\">'Time'<\/span><span style=\"color: #339933;\">,<\/span>\r\n\t\tylab = <span style=\"color: #0000ff;\">'Y'<\/span><span style=\"color: #339933;\">,<\/span> las = <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Plot the polygons using the output from the polylims function<\/span>\r\n<span style=\"color: #000000; font-weight: bold;\">for<\/span><span style=\"color: #009900;\">(<\/span>i <span style=\"color: #000000; font-weight: bold;\">in<\/span> <span style=\"color: #cc66cc;\">1<\/span><span>:<\/span><a href=\"http:\/\/inside-r.org\/r-doc\/base\/length\"><span style=\"color: #003399; font-weight: bold;\">length<\/span><\/a><span style=\"color: #009900;\">(<\/span>polys<span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #009900;\">{<\/span>\r\n\t<a href=\"http:\/\/inside-r.org\/r-doc\/graphics\/polygon\"><span style=\"color: #003399; font-weight: bold;\">polygon<\/span><\/a><span style=\"color: #009900;\">(<\/span>polys<span style=\"color: #009900;\">[<\/span><span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span>$<\/span>x<span style=\"color: #339933;\">, <\/span>polys<span style=\"color: #009900;\">[<\/span><span style=\"color: #009900;\">[<\/span>i<span style=\"color: #009900;\">]<\/span><span style=\"color: #009900;\">]<\/span><span>$<\/span>y<span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/inside-r.org\/r-doc\/base\/col\"><span style=\"color: #003399; font-weight: bold;\">col<\/span><\/a> = <a href=\"http:\/\/inside-r.org\/r-doc\/grDevices\/rgb\"><span style=\"color: #003399; font-weight: bold;\">rgb<\/span><\/a><span style=\"color: #009900;\">(<\/span><span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #cc66cc;\">0.5<\/span><span style=\"color: #009900;\">)<\/span><span style=\"color: #339933;\">,<\/span> border = <span style=\"color: #000000; font-weight: bold;\">NA<\/span><span style=\"color: #009900;\">)<\/span>\r\n<span style=\"color: #009900;\">}<\/span>\r\n<span style=\"color: #666666; font-style: italic;\"># Replot the main y line again on top of the polygon<\/span>\r\n<a href=\"http:\/\/inside-r.org\/r-doc\/graphics\/lines\"><span style=\"color: #003399; font-weight: bold;\">lines<\/span><\/a><span style=\"color: #009900;\">(<\/span>mydata<span>$<\/span>times<span style=\"color: #339933;\">, <\/span>mydata<span>$<\/span>y<span style=\"color: #339933;\">,<\/span> lwd = <span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/inside-r.org\/r-doc\/base\/col\"><span style=\"color: #003399; font-weight: bold;\">col<\/span><\/a> = <span style=\"color: #0000ff;\">'black'<\/span><span style=\"color: #009900;\">)<\/span><\/pre>\n<\/div>\n<\/div>\n<p>The for loop in the middle steps through each of the items in the &#8216;polys&#8217; list, extracts the x&amp;y values, and uses them to draw the polygon. After drawing the polygon, it&#8217;s usually a good idea to replot the original line over top, since the polygon may obscure it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every so often I want to plot some data with pretty upper and lower error bounds, such as temperature data through time, perhaps with the maximum and minimum temperature range or standard error bounds for averaged data. The polygon( ) function can make those sorts of pretty plots. However, I&#8217;ll often have chunks of missing [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[218],"tags":[17,149,58],"class_list":["post-1406","post","type-post","status-publish","format-standard","hentry","category-r-project","tag-plotting","tag-polygon","tag-r-project"],"_links":{"self":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1406","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/comments?post=1406"}],"version-history":[{"count":6,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1406\/revisions"}],"predecessor-version":[{"id":1413,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1406\/revisions\/1413"}],"wp:attachment":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/media?parent=1406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/categories?post=1406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/tags?post=1406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}