{"id":13712091,"url":"https://github.com/AtherEnergy/ggTimeSeries","last_synced_at":"2025-05-06T21:33:09.339Z","repository":{"id":6289658,"uuid":"55284200","full_name":"AtherEnergy/ggTimeSeries","owner":"AtherEnergy","description":"Time series visualisation","archived":false,"fork":false,"pushed_at":"2022-02-11T18:59:37.000Z","size":2933,"stargazers_count":251,"open_issues_count":7,"forks_count":39,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-11-13T22:35:29.018Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AtherEnergy.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-02T08:00:22.000Z","updated_at":"2024-10-21T23:11:08.000Z","dependencies_parsed_at":"2022-08-06T19:15:27.640Z","dependency_job_id":null,"html_url":"https://github.com/AtherEnergy/ggTimeSeries","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtherEnergy%2FggTimeSeries","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtherEnergy%2FggTimeSeries/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtherEnergy%2FggTimeSeries/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtherEnergy%2FggTimeSeries/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AtherEnergy","download_url":"https://codeload.github.com/AtherEnergy/ggTimeSeries/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252772296,"owners_count":21801903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T23:01:14.837Z","updated_at":"2025-05-06T21:33:08.974Z","avatar_url":"https://github.com/AtherEnergy.png","language":"R","funding_links":[],"categories":["Plot layers","Time"],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, echo = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"README-\"\n)\n```\n\n\n## About\n\nThis R package offers novel time series visualisations. It is based on\n`ggplot2` and offers `geom`s and pre-packaged functions for easily\ncreating any of the offered charts. Some examples are listed below.\n\nThis package can be installed from github by installing `devtools`\nlibrary and then running the following command -\n`devtools::install_github('Ather-Energy/ggTimeSeries')`.\n\n## Line Charts Legacy\n\nIoT devices generate a lot of sequential data over time, also called\ntime series data. Legacy portrayals of such data would centre around\nline charts. Line charts have reportedly been around since the early\n1700s (source: Wikipedia) and we have nothing against them. They\nfacilitate trend detection and comparison, are simple to draw, and easy\nto understand; all in all a very well behaved visualisation. In modern\ntimes, their use is widespread from the heartbeat monitor at a hospital\nto the multiple-monitor display at a trader’s\ndesk.\n\n    ## [1] \"Excel 97 look recreated in R with the ggthemes package\"\n\n![Excel97 Linechart](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/excel97_line-1.png?raw=true)\n\n## Alternatives\n\nHowever there are cases when the data scientist becomes more demanding\nand specific. Five alternatives available to such a data scientist are\nlisted below. All of these options are available as `geom`s or packaged\nfunctions in the `ggplot2` based `ggTimeSeries` package.\n\nBefore that, setting a minimal theme -\n\n```r\nminimalTheme = theme_set(theme_bw(12))\nminimalTheme = theme_update(\n   axis.ticks = element_blank(),\n   legend.position = 'none',\n   strip.background = element_blank(),\n   panel.border = element_blank(),\n   panel.background = element_blank(),\n   panel.grid = element_blank()\n)\n```\n\n### Calendar Heatmap\n\nAvailable as `stat_calendar_heatmap` and `ggplot_calendar_heatmap`.\n\nA calendar heatmap is a great way to visualise daily data. Its structure\nmakes it easy to detect weekly, monthly, or seasonal patterns.\n\n```r\n# creating some data\nset.seed(1)\ndtData = data.table(\n      DateCol = seq(\n         as.Date(\"1/01/2014\", \"%d/%m/%Y\"),\n         as.Date(\"31/12/2015\", \"%d/%m/%Y\"),\n         \"days\"\n      ),\n      ValueCol = runif(730)\n   )\ndtData[, ValueCol := ValueCol + (strftime(DateCol,\"%u\") %in% c(6,7) * runif(1) * 0.75), .I]\ndtData[, ValueCol := ValueCol + (abs(as.numeric(strftime(DateCol,\"%m\")) - 6.5)) * runif(1) * 0.75, .I]\n\n# base plot\np1 = ggplot_calendar_heatmap(\n   dtData,\n   'DateCol',\n   'ValueCol'\n)\n\n# adding some formatting\np1 +\n   xlab(NULL) +\n   ylab(NULL) +\n   scale_fill_continuous(low = 'green', high = 'red') +\n   facet_wrap(~Year, ncol = 1)\n```\n![Calendar Heatmap](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/calendar_heatmap-1.png?raw=true)\n\n```r\n# creating some categorical data\ndtData[, CategCol := letters[1 + round(ValueCol * 7)]]\n\n# base plot\np2 = ggplot_calendar_heatmap(\n   dtData,\n   'DateCol',\n   'CategCol'\n)\n\n# adding some formatting\np2 +\n   xlab(NULL) +\n   ylab(NULL) +\n   facet_wrap(~Year, ncol = 1)\n```\n\n![Calendar Heatmap 2](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/calendar_heatmap-2.png?raw=true)\n\n### Horizon Plots\n\nAvailable as `stat_horizon` and `ggplot_horizon`.\n\nImagine an area chart which has been chopped into multiple chunks of\nequal height. If you overlay these chunks one on top of the the other,\nand colour them to indicate which chunk it is, you get a horizon plot.\nHorizon plots are useful when visualising y values spanning a vast range\nbut with a skewed distribution, and / or trying to highlight outliers\nwithout losing context of variation in the rest of the data.\n\n```r\n# creating some data\nset.seed(1)\ndfData = data.frame(x = 1:1000, y = cumsum(rnorm(1000)))\n\n# base plot\np1 = ggplot_horizon(dfData, 'x', 'y')\n\n\nprint(\"If you're seeing any vertical white stripes, it's a display thing.\")\n```\n\n    ## [1] \"If you're seeing any vertical white stripes, it's a display thing.\"\n\n```r\n# adding some formatting\np1 +\n   xlab(NULL) +\n   ylab(NULL) +\n   scale_fill_continuous(low = 'green', high = 'red') +\n   coord_fixed( 0.5 * diff(range(dfData$x)) / diff(range(dfData$y)))\n```\n\n![Horizon Plot](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/horizon-1.png?raw=true)\n\n### Steamgraphs\n\nAvailable as `stat_steamgraph`.\n\nA steamgraph is a more aesthetically appealing version of a stacked area\nchart. It tries to highlight the changes in the data by placing the\ngroups with the most variance on the edges, and the groups with the\nleast variance towards the centre. This feature in conjunction with the\ncentred alignment of each of the contributing areas makes it easier for\nthe viewer to compare the contribution of any of the components across\ntime.\n\n```r\n# creating some data\nset.seed(10)\ndfData = data.frame(\n   Time = 1:1000,\n   Signal = abs(\n      c(\n         cumsum(rnorm(1000, 0, 3)),\n         cumsum(rnorm(1000, 0, 4)),\n         cumsum(rnorm(1000, 0, 1)),\n         cumsum(rnorm(1000, 0, 2))\n      )\n   ),\n   VariableLabel = c(rep('Class A', 1000), rep('Class B', 1000), rep('Class C', 1000), rep('Class D', 1000))\n)\n\n# base plot\np1 = ggplot(dfData, aes(x = Time, y = Signal, group = VariableLabel, fill = VariableLabel)) +\n  stat_steamgraph()\n\n\n# adding some formatting\np1 +\n   xlab(NULL) +\n   ylab(NULL) +\n   coord_fixed( 0.2 * diff(range(dfData$Time)) / diff(range(dfData$Signal)))\n```\n\n![Steamgraph Plot](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/steamgraph-1.png?raw=true)\n\n### Waterfall\n\nAvailable as `stat_waterfall` and `ggplot_waterfall`.\n\nRather than the values itself, a waterfall plot tries to bring out the\nchanges in the values.\n\n```r\n# creating some data\nset.seed(1)\ndfData = data.frame(x = 1:100, y = cumsum(rnorm(100)))\n\n# base plot\np1 = ggplot_waterfall(\n   dtData = dfData,\n   'x',\n   'y'\n)\n\n# adding some formatting\np1 +\n   xlab(NULL) +\n   ylab(NULL)\n```\n\n![Waterfall Plot](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/waterfall-1.png?raw=true)\n\n### Occurrence Dot Plot\n\nAvailable as `stat_occurrence`.\n\nThis one is a favourite in infographics. For rare events, the reader\nwould find it convenient to have the count of events encoded in the\nchart itself instead of having to map the value back to the Y axis.\n\n```r\n# creating some data\nset.seed(1)\ndfData = data.table(x = 1:100, y = floor(4 * abs(rnorm(100, 0 , 0.4))))\n\n# base plot\np1 = ggplot(dfData, aes(x =x, y = y) )+\n   stat_occurrence()\n\n# adding some formatting\np1 +\n   xlab(NULL) +\n   ylab(NULL) +\n   coord_fixed(ylim = c(0,1 + max(dfData$y)))\n```\n\n![Occurance Dotplot](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/occurrence_dotplot-1.png?raw=true)\n\n### Marimekko or Mosaik\n\nAvailable as `stat_marimekko`.\n\nA marimekko plot, or a mosaic plot, visualises the co-occurrence of two\ncategorical / ordinal variables. In case of a time series, it could be\nused to visualise the proportion of transitions from one state to\nanother by considering each state to be a category and plotting the\noccurrence of current category vs. the next category. The span on the\nhorizontal represents the overall occurrence of the xbucket argument.\nThe span on the vertical represents the marginal occurrence of the\nybucket argument when xbucket was the previous state. The area of a\nblock indicates the proportion of occurrence of that pair in the entire\ndataset.\n\n```r\n# creating some data\nset.seed(1)\n\ndfData = data.frame(Signal = pmax(pmin(rnorm(10000), 3), -3))\n\ndfData2 = data.frame(\n   Signal = round(head(dfData$Signal, -1),0),\n   NextSignal = round(tail(dfData$Signal, -1),0),\n   Weight = 1\n)\n\n# base plot\np1 = ggplot(dfData2, aes(xbucket = Signal, ybucket = NextSignal, fill = NextSignal, weight = Weight) )+\n   stat_marimekko(color = 'black', xlabelyposition = -0.1)\n\n# adding some formatting\np1 +\n   xlab('Signal occurrence %') +\n   ylab('Signal | Next signal occurrence %') +\n   scale_x_continuous(breaks = 0:10/10) +\n   scale_y_continuous(breaks = 0:10/10)\n```\n\n![Marimekko Plot](https://github.com/JesseVent/ggTimeSeries/blob/581fa14a6bbf71dd1c30190244ffdce9646900e1/README_files/figure-markdown_strict/marimekko-1.png?raw=true)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAtherEnergy%2FggTimeSeries","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAtherEnergy%2FggTimeSeries","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAtherEnergy%2FggTimeSeries/lists"}