{"id":249,"date":"2013-07-02T15:47:41","date_gmt":"2013-07-02T20:47:41","guid":{"rendered":"http:\/\/homepages.uc.edu\/~yaozo\/wordpress\/?p=249"},"modified":"2013-07-02T15:47:41","modified_gmt":"2013-07-02T20:47:41","slug":"plotting-a-3d-surface-plot-with-contour-map-overlay-using-r","status":"publish","type":"post","link":"https:\/\/zhuoyao.net\/index.php\/2013\/07\/02\/plotting-a-3d-surface-plot-with-contour-map-overlay-using-r\/","title":{"rendered":"Plotting a 3D surface plot with contour map overlay, using R"},"content":{"rendered":"<p>I have a 3-tuple data set (X,Y,Z points) that I want to plot using R.<\/p>\n<p>I want to create a surface plot from the data, and superimpose a contour map on the surface plot, so as to create the impression of the contour map being the &#8220;shadow&#8221; or projection from the surface plot. The contour map is to appear below the surface plot.<\/p>\n<p>My data set looks somewhat like this:<\/p>\n<pre><code>Axis  |  Data Type\n-------------------\nX     |  Date value\nY     |  Float value\nZ     |  Float value<\/code><\/pre>\n<p>How can I achieve this?<\/p>\n<p>&nbsp;<\/p>\n<p>I just saw that you pointed out one of your dimensions is a date. In that case,\u00a0<a href=\"http:\/\/www.quantmod.com\/examples\/chartSeries3d\/\">have a look at Jeff Ryan&#8217;s chartSeries3d<\/a>\u00a0which is designed to chart 3-dimensional time series. Here he shows the yield curve over time:<\/p>\n<p><img decoding=\"async\" alt=\"chartSeries example\" src=\"http:\/\/www.quantmod.com\/examples\/chartSeries3d\/chartSeries3d-thumb.png\" \/><\/p>\n<p><em>Original Answer:<\/em><\/p>\n<p>As I understand it, you want a countour map to be the projection on the plane beneath the 3D surface plot. I don&#8217;t believe that there&#8217;s an easy way to do this other than creating the two plots and then combining them. You may\u00a0<a href=\"http:\/\/cran.r-project.org\/web\/views\/Spatial.html\">find the spatial view helpful for this<\/a>.<\/p>\n<p>There are two primary R packages for 3D plotting:\u00a0<strong><a href=\"http:\/\/cran.r-project.org\/web\/packages\/rgl\/\">rgl<\/a><\/strong>\u00a0(or you can use the related\u00a0<a href=\"http:\/\/cran.r-project.org\/web\/packages\/rgl\/\">misc3d<\/a>\u00a0package) and<strong><a href=\"http:\/\/cran.r-project.org\/web\/packages\/scatterplot3d\/\">scatterplot3d<\/a><\/strong>.<\/p>\n<p><strong>rgl<\/strong><\/p>\n<p>The rgl package uses OpenGL to create interactive 3D plots (<a href=\"http:\/\/rgl.neoscientists.org\/\">read more on the rgl website<\/a>). Here&#8217;s an example using the\u00a0<code>surface3d<\/code>\u00a0function:<\/p>\n<pre><code>library(rgl)\ndata(volcano)\nz &lt;- 2 * volcano # Exaggerate the relief\nx &lt;- 10 * (1:nrow(z)) # 10 meter spacing (S to N)\ny &lt;- 10 * (1:ncol(z)) # 10 meter spacing (E to W)\nzlim &lt;- range(y)\nzlen &lt;- zlim[2] - zlim[1] + 1\ncolorlut &lt;- terrain.colors(zlen,alpha=0) # height color lookup table\ncol &lt;- colorlut[ z-zlim[1]+1 ] # assign colors to heights for each point\nopen3d()\nrgl.surface(x, y, z, color=col, alpha=0.75, back=\"lines\")<\/code><\/pre>\n<p>The alpha parameter makes this surface partly transparent. Now you have an interactive 3D plot of a surface and you want to create a countour map underneath. rgl allows you add more plots to an existing image:<\/p>\n<pre><code>colorlut &lt;- heat.colors(zlen,alpha=1) # use different colors for the contour map\ncol &lt;- colorlut[ z-zlim[1]+1 ] \nrgl.surface(x, y, matrix(1, nrow(z), ncol(z)),color=col, back=\"fill\")<\/code><\/pre>\n<p>In this surface I set the heights=1 so that we have a plane underneath the other surface. This ends up looking like this, and can be rotated with a mouse:<\/p>\n<p><img decoding=\"async\" alt=\"3D surface plot\" src=\"http:\/\/i45.tinypic.com\/12637gy.jpg\" \/><\/p>\n<p><strong>scatterplot3d<\/strong><\/p>\n<p>scatterplot3d is a little more like other plotting functions in R (<a href=\"http:\/\/cran.r-project.org\/web\/packages\/scatterplot3d\/vignettes\/s3d.pdf\">read the vignette<\/a>). Here&#8217;s a simple example:<\/p>\n<pre><code>temp &lt;- seq(-pi, 0, length = 50)\nx &lt;- c(rep(1, 50) %*% t(cos(temp)))\ny &lt;- c(cos(temp) %*% t(sin(temp)))\nz &lt;- c(sin(temp) %*% t(sin(temp)))\nscatterplot3d(x, y, z, highlight.3d=TRUE,\n col.axis=\"blue\", col.grid=\"lightblue\",\n main=\"scatterplot3d - 2\", pch=20)<\/code><\/pre>\n<p>In this case, you will need to overlay the images. The R-Wiki\u00a0<a href=\"http:\/\/wiki.r-project.org\/rwiki\/doku.php?id=tips%3Agraphics-misc%3Atranslucency\">has a nice post on creating a tanslucent background image<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have a 3-tuple data set (X,Y,Z points) that I want to plot using R. I want to create a surface plot from the data,&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-249","post","type-post","status-publish","format-standard","hentry","category-r"],"_links":{"self":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/249","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/comments?post=249"}],"version-history":[{"count":0,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/249\/revisions"}],"wp:attachment":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/media?parent=249"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/categories?post=249"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/tags?post=249"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}