{"id":661,"date":"2014-07-15T09:49:31","date_gmt":"2014-07-15T16:49:31","guid":{"rendered":"http:\/\/homepages.uc.edu\/~yaozo\/wordpress\/?p=661"},"modified":"2014-07-15T09:49:31","modified_gmt":"2014-07-15T16:49:31","slug":"horizon-on-ggplot2","status":"publish","type":"post","link":"https:\/\/zhuoyao.net\/index.php\/2014\/07\/15\/horizon-on-ggplot2\/","title":{"rendered":"Horizon on ggplot2"},"content":{"rendered":"<p style=\"color: #777777;\">SocialDataBlog\u2019s kind reference in post\u00a0<a style=\"color: #0088cc;\" title=\"http:\/\/socialdatablog.com\/horizon-plots-with-ggplot-not\/\" href=\"http:\/\/socialdatablog.com\/horizon-plots-with-ggplot-not\/\" target=\"_blank\" rel=\"noopener\">Horizon plots with ggplot (not)<\/a>\u00a0motivated me to finish what the post started.\u00a0 I knew that ggplot2 would be a little more difficult to use for the purpose of a\u00a0<a style=\"color: #0088cc;\" href=\"http:\/\/timelyportfolio.blogspot.com\/search\/label\/horizonplot\" target=\"_blank\" rel=\"noopener\">horizon plot<\/a>, but I felt compelled to provide at least one example of a horizon plot for each of the major R graphing packages.\u00a0 I achieved a good result but the code is not as elegant or as flexible as I would like.\u00a0 Readers more comfortable with ggplot2, please bash, fork, and improve.<\/p>\n<table style=\"color: #777777;\">\n<tbody>\n<tr>\n<td><a style=\"color: #0088cc;\" href=\"https:\/\/picasaweb.google.com\/lh\/photo\/-fYTaEIicaNEQxEUECoPutMTjNZETYmyPJy0liipFm0?feat=embedwebsite\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/-wp-VaAbiRSc\/UDxJiL0qpfI\/AAAAAAACsB8\/Z9grArcTzsY\/s800\/ggplot2%2520horizon%2520plot.png\" alt=\"\" width=\"640\" height=\"500\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td>From\u00a0<a style=\"color: #0088cc;\" href=\"https:\/\/picasaweb.google.com\/115099029813395778077\/TimelyPortfolio02?authuser=0&amp;feat=embedwebsite\">TimelyPortfolio<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"color: #777777;\"><a style=\"color: #0088cc;\" href=\"https:\/\/gist.github.com\/3494996\" target=\"_blank\" rel=\"noopener\">R code in GIST (do raw for copy\/paste):<\/a><\/p>\n<pre style=\"color: #000000;\">#first attempt at implementing horizon plots in ggplot2\n#pleased with result but code sloppy and inflexible\n#as always very open to improvements and forks\n\nrequire(ggplot2)\nrequire(reshape2)\nrequire(quantmod)\nrequire(PerformanceAnalytics)\nrequire(xtsExtra)\n\ndata(edhec)\norigin = 0\nhorizonscale = 0.1\n#get 12 month rolling return of edhec indexes\nroc &lt;- as.xts(apply(cumprod(edhec+1),MARGIN=2,ROC,n=12,type=\"discrete\"),order.by=index(edhec))\n\nroc.df &lt;- as.data.frame(cbind(index(roc),coredata(roc)))\nroc.melt &lt;- melt(roc.df,id.vars=1)\nroc.melt[,1] &lt;- as.Date(roc.melt[,1])  #convert back to a Date\n\n\nhorizon.panel.ggplot &lt;- function(df, title) {\n  #df parameter should be in form of date (x), grouping, and a value (y)\n  colnames(df) &lt;- c(\"date\",\"grouping\",\"y\")\n  #get some decent colors from RColorBrewer\n  #we will use colors on the edges so 2:4 for red and 7:9 for blue\n  require(RColorBrewer)\n  col.brew &lt;- brewer.pal(name=\"RdBu\",n=10)\n  \n  #get number of bands for the loop\n  #limit to 3 so it will be much more manageable\n  nbands = 3\n\n  #loop through nbands to add a column for each of the positive and negative bands\n  for (i in 1:nbands) {\n    #do positive\n    df[,paste(\"ypos\",i,sep=\"\")] &lt;- ifelse(df$y &gt; origin,\n                                          ifelse(abs(df$y) &gt; horizonscale * i,\n                                                 horizonscale,\n                                                 ifelse(abs(df$y) - (horizonscale * (i - 1) - origin) &gt; origin, abs(df$y) - (horizonscale * (i - 1) - origin), origin)),\n                                          origin)\n    #do negative\n    df[,paste(\"yneg\",i,sep=\"\")] &lt;- ifelse(df$y &lt; origin,\n                                          ifelse(abs(df$y) &gt; horizonscale * i,\n                                                 horizonscale,\n                                                 ifelse(abs(df$y) - (horizonscale * (i - 1) - origin) &gt; origin, abs(df$y) - (horizonscale * (i - 1) - origin), origin)),\n                                          origin)\n  }\n  #melt data frame now that we have added a column for each band\n  #this will fit ggplot2 expectations and make it much easier\n  df.melt &lt;- melt(df[,c(1:2,4:9)],id.vars=1:2)    \n  #name the columns for reference\n  #try to be generic\n  colnames(df.melt) &lt;- c(\"date\",\"grouping\",\"band\",\"value\")\n  \n  #use ggplot to produce an area plot\n  p &lt;- ggplot(data=df.melt) +\n    geom_area(aes(x = date, y = value, fill=band),\n              #alpha=0.25,\n              position=\"identity\") +  #this means not stacked\n    scale_fill_manual(values=c(\"ypos1\"=col.brew[7],  #assign the colors to each of the bands; colors get darker as values increase\n                               \"ypos2\"=col.brew[8],\n                               \"ypos3\"=col.brew[9],\n                               \"yneg1\"=col.brew[4],\n                               \"yneg2\"=col.brew[3],\n                               \"yneg3\"=col.brew[2])) +\n    ylim(origin,horizonscale) +   #limit plot to origin and horizonscale\n    facet_grid(grouping ~ .) +    #do new subplot for each group\n    theme_bw() +                  #this is optional, but I prefer to default\n    opts(legend.position = \"none\",    #remove legend\n          strip.text.y = theme_text(),#rotate strip text to horizontal \n          axis.text.y = theme_blank(),#remove y axis labels\n          axis.ticks = theme_blank(), #remove tick marks\n          axis.title.y = theme_blank(),#remove title for the y axis\n          axis.title.x = theme_blank(),#remove title for the x axis\n          title = title,               #add a title from function parameter\n         plot.title = theme_text(size=16, face=\"bold\", hjust=0)) #format title\n  \n  return(p)\n}\n\n\n\nhorizon.panel.ggplot(roc.melt, \"EDHEC Indexes Return (Rolling 1 Year)\")<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>SocialDataBlog\u2019s kind reference in post\u00a0Horizon plots with ggplot (not)\u00a0motivated me to finish what the post started.\u00a0 I knew that ggplot2 would be a little more&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-661","post","type-post","status-publish","format-standard","hentry","category-r"],"_links":{"self":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/661","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=661"}],"version-history":[{"count":0,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/661\/revisions"}],"wp:attachment":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/media?parent=661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/categories?post=661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/tags?post=661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}