{"id":1127,"date":"2012-03-11T18:32:14","date_gmt":"2012-03-11T22:32:14","guid":{"rendered":"http:\/\/lukemiller.org\/?p=1127"},"modified":"2012-03-11T18:32:14","modified_gmt":"2012-03-11T22:32:14","slug":"plotting-stuff-on-an-image","status":"publish","type":"post","link":"https:\/\/lukemiller.org\/index.php\/2012\/03\/plotting-stuff-on-an-image\/","title":{"rendered":"Plotting stuff on an image"},"content":{"rendered":"<p>Recently, I needed to figure out how many extension cords I was going to need to buy in order to reach parts of my field site. Wandering around in the field with a surveyor&#8217;s tape was an option, but so was plotting distances on an aerial image I had of my site. What follows is a brief walk through of how I plotted stuff on top of my image in R (the open-source statistical computer software language, available at <a href=\"http:\/\/www.r-project.org\/\">http:\/\/www.r-project.org\/<\/a>).<\/p>\n<figure id=\"attachment_1137\" aria-describedby=\"caption-attachment-1137\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1137\" title=\"HMS_cable_distances_sm\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm-300x300.jpg 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm-150x150.jpg 150w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1137\" class=\"wp-caption-text\">My final image with elements overlain on the original image using R.<\/figcaption><\/figure>\n<p>The original aerial image was 1500 x 1500 pixels. I figured out the scale in the image by opening the image in the external program <a href=\"http:\/\/rsbweb.nih.gov\/ij\/\">ImageJ<\/a> and measuring the number of pixels that made up one of the building sides (that I had previously measured in real life). Based on this, I determined that 1 pixel in my image was equal to 6 inches on the ground.<\/p>\n<figure id=\"attachment_1136\" aria-describedby=\"caption-attachment-1136\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_aerial_sm.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1136\" title=\"HMS_aerial_sm\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_aerial_sm-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_aerial_sm-300x300.jpg 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_aerial_sm-150x150.jpg 150w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_aerial_sm.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1136\" class=\"wp-caption-text\">The original image.<\/figcaption><\/figure>\n<p>Since my goal was to get power out to my sites temporarily, I wanted to show the radius around each of the closest electrical sources that I could plug an extension cord into. Therefore, I needed to know the location of each of my three power sources in terms of their pixel coordinates in my image. That would require loading the image into a R plotting window and using the <code>locator()<\/code> function to find those pixel values.<\/p>\n<p>I began by reading the jpeg image into R using the <code>read.jpeg<\/code> function from the <code>ReadImages<\/code> package.<\/p>\n<pre>library(ReadImages) # load the ReadImages package\r\nj &lt;- read.jpeg(file.choose()) # open the jpeg image and read it into an object 'j'<\/pre>\n<p>The image is imported as a 1500 x 1500 x 3 matrix. The next step is to plot the image in a R figure window. I wanted the figure to fill the window, so I started by setting all of the figure margins to 0, and then making a blank figure with the proper x and y dimensions to hold my image. Since I know my image is 1500&#215;1500 pixels, I set the x limits and y limits to run from 0 to 1500. Then the <code>rasterImage<\/code> function plotted the image into the figure.<\/p>\n<pre>par(mar = c(0,0,0,0)) # set zero margins on all 4 sides\r\nplot(x = NULL, y = NULL, xlim = c(0,1500), ylim = c(0,1500), pch = '',\r\n\t\txaxt = 'n', yaxt = 'n', xlab = '', ylab = '', xaxs = 'i', yaxs = 'i',\r\n\t\tbty = 'n') # plot empty figure\r\nrasterImage(j, xleft = 0, ybottom = 0, xright = 1500, ytop = 1500) # plot jpeg<\/pre>\n<p>The plotting of the image takes a few seconds, since it&#8217;s a lot of information to plot. The resulting image should completely fill the R figure window.<\/p>\n<p>The next step was to determine the location of my electrical sources with reference to the dimensions of the figure. The <code>locator()<\/code> function is designed for this kind of thing.<\/p>\n<pre>locs &lt;- locator(3) # I want to locate 3 points<\/pre>\n<p>Once you enter the <code>locator()<\/code> command, if you mouse over the figure your pointer should turn into a cross. Click on each of the points you want to store, and the x and y values will be stored in the <code>locs<\/code> object.<\/p>\n<p>I wanted to plot a set of concentric circles located over the top of each of the three points I located. I wanted the circles to have diameters of 100, 200, and 300 ft to show how far I could get from each location with a string of 100ft long extension cords. Since I already knew that each pixel in the image is 6 inches on the ground, then one foot equals 2 pixels, and thus 100 ft on the ground equals 200 pixels in my image. A circle with a radius of 100ft on the ground would have a radius of 200 pixels on the image, while a circle with a 200ft radius would have a radius of 400 pixels, and a circle of radius 300ft would have a radius of 600 pixels. I used the <code>symbols()<\/code> function to plot the circles, and inside of the <code>symbols()<\/code> function I used the <code>rgb()<\/code> to specify the color and transparency of each circle.<\/p>\n<p>We&#8217;ll plot the first 300ft radius (= 600 pixels) circle on top of the first point stored in <code>locs<\/code> as follows:<\/p>\n<pre>symbols(x = locs$x[1], y = locs$y[1], circles = 600,\r\n\t\tfg = 'grey', bg = rgb(0.6, 0, 0, 0.15), add = TRUE,\r\n                inches = FALSE, lwd = 2)<\/pre>\n<p>In the code above, the center of the circle is given using the 1st values stored in the x and y items within <code>locs<\/code>. The color of the edge of the circle is defined by naming the color grey, while the fill color (background color, aka &#8216;bg&#8217;) of the circle is defined using the <code>rgb()<\/code> function, which takes 4 arguments. The first three arguments are red, green, and blue values (in that order, r-g-b) from 0 to 1. I only had one value, 0.6, for red, while the green and blue values were both zero. The fourth argument is the alpha transparency value, again from 0 to 1. My value of 0.15 is very low, so the color is mostly see-through. The other arguments to <code>symbols<\/code> can be found by typing <code>?symbols<\/code> at the R command line.<\/p>\n<figure id=\"attachment_1142\" aria-describedby=\"caption-attachment-1142\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1142\" title=\"HMS_cable_distances_sm_2\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_2-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_2-300x300.jpg 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_2-150x150.jpg 150w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_2.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1142\" class=\"wp-caption-text\">Plotting the first circle at the first location.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>Plotting the 200ft radius circle at the first location uses very similar code, except the circle radius value is shrunk.<\/p>\n<pre>symbols(x = locs$x[1], y = locs$y[1], circles = 400,\r\n\t\tfg = 'grey', bg = rgb(0.6, 0, 0, 0.15), add = TRUE,\r\n                inches = FALSE, lwd = 2)<\/pre>\n<figure id=\"attachment_1143\" aria-describedby=\"caption-attachment-1143\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1143\" title=\"HMS_cable_distances_sm_3\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_3-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_3-300x300.jpg 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_3-150x150.jpg 150w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_3.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1143\" class=\"wp-caption-text\">The 2nd, smaller circle is plotted at the same location. Notice that transparency changes as you plot multiple transparent objects on top of each other.<\/figcaption><\/figure>\n<p>Plotting circles at the other locations involves using different x and y values from <code>locs<\/code>, and changing the color values. For example, the smallest circle at my second location and the largest circle at the third location would be plotted like this:<\/p>\n<pre># Plot the 100ft radius circle at the second location\r\nsymbols(x = locs$x[2], y = locs$y[2], circles = 200,\r\n\t\tfg = 'grey', bg = rgb(0, 0.6, 0, 0.15), add = TRUE,\r\n                inches = FALSE, lwd = 2)\r\n# Plot the 300ft radius circle at the third location\r\nsymbols(x = locs$x[3], y = locs$y[3], circles = 600,\r\n\t\tfg = 'grey', bg = rgb(0, 0, 0.6, 0.15), add = TRUE,\r\n                inches = FALSE, lwd = 2)<\/pre>\n<figure id=\"attachment_1144\" aria-describedby=\"caption-attachment-1144\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_4.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1144\" title=\"HMS_cable_distances_sm_4\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_4-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_4-300x300.jpg 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_4-150x150.jpg 150w, https:\/\/lukemiller.org\/wp-content\/uploads\/2012\/03\/HMS_cable_distances_sm_4.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1144\" class=\"wp-caption-text\">The figure after plotting two more circles.<\/figcaption><\/figure>\n<p>I also plotted a little point over the center of my locations. To do this I used the x and y values once again, with the <code>points()<\/code> function.<\/p>\n<pre>points(x = locs$x[1], y = locs$y[1], pch = 20, col = 'red')\r\npoints(x = locs$x[2], y = locs$y[2], pch = 20, col = 'blue')\r\npoints(x = locs$x[3], y = locs$y[3], pch = 20, col = 'green')<\/pre>\n<p>Finally, I put a scale bar in the upper right corner. I chose the location by manually inputting x and y values (since I know the maximum dimensions of the figure are still 1500&#215;1500). The <code>lines()<\/code> function draws the line, and the <code>text()<\/code> function writes the label.<\/p>\n<pre># Plot scale bar in corner\r\nlines(x = c(1200,1400), y = c(1200,1200), lwd = 2, col = 'white')\r\ntext(x = 1300, y = 1230, labels = '100 ft', col = 'white')<\/pre>\n<p>In practice, I wrote all of these steps (and the extra steps not shown above) into a R script so that I could experiment with changing colors and line widths without having to retype everything at the R command line. You could also use <code>for<\/code> loops to reduce some of the redundant circle plotting commands. The output can be saved as a jpeg or in several other formats, either using the menu on the figure window, or by wrapping all of the plotting commands inside <code>jpeg()<\/code> and <code>dev.off()<\/code> calls.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently, I needed to figure out how many extension cords I was going to need to buy in order to reach parts of my field site. Wandering around in the field with a surveyor&#8217;s tape was an option, but so was plotting distances on an aerial image I had of my site. What follows is a brief walk through of how I plotted stuff on top of my image in R.<\/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":[122,121,120,119,124,123],"class_list":["post-1127","post","type-post","status-publish","format-standard","hentry","category-r-project","tag-figure-margins","tag-image-plotting","tag-jpeg","tag-rasterimage","tag-rgb","tag-symbol"],"_links":{"self":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1127","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=1127"}],"version-history":[{"count":25,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1127\/revisions"}],"predecessor-version":[{"id":1157,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1127\/revisions\/1157"}],"wp:attachment":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/media?parent=1127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/categories?post=1127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/tags?post=1127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}