{"id":13665938,"url":"https://github.com/hrbrmstr/ggalt","last_synced_at":"2025-05-15T14:07:56.639Z","repository":{"id":48454717,"uuid":"42136902","full_name":"hrbrmstr/ggalt","owner":"hrbrmstr","description":":earth_americas: Extra Coordinate Systems, Geoms,  Statistical Transformations \u0026 Scales for 'ggplot2'","archived":false,"fork":false,"pushed_at":"2024-04-03T01:51:15.000Z","size":26281,"stargazers_count":677,"open_issues_count":58,"forks_count":98,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-04-07T18:11:08.698Z","etag":null,"topics":["geom","ggplot-extension","ggplot2","ggplot2-geom","ggplot2-scales","r","rstats"],"latest_commit_sha":null,"homepage":"https://cran.r-project.org/web/packages/ggalt/vignettes/ggalt_examples.html","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/hrbrmstr.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"hrbrmstr"}},"created_at":"2015-09-08T20:21:28.000Z","updated_at":"2025-04-04T12:32:23.000Z","dependencies_parsed_at":"2022-09-15T14:11:49.475Z","dependency_job_id":"389cb226-c1fb-4a85-956a-7e0cb0fbd720","html_url":"https://github.com/hrbrmstr/ggalt","commit_stats":{"total_commits":110,"total_committers":14,"mean_commits":7.857142857142857,"dds":0.4636363636363636,"last_synced_commit":"8941f8c9b13ac38ca0cf6500951017c35241de28"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Fggalt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Fggalt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Fggalt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Fggalt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hrbrmstr","download_url":"https://codeload.github.com/hrbrmstr/ggalt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355335,"owners_count":22057354,"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":["geom","ggplot-extension","ggplot2","ggplot2-geom","ggplot2-scales","r","rstats"],"created_at":"2024-08-02T06:00:54.367Z","updated_at":"2025-05-15T14:07:51.603Z","avatar_url":"https://github.com/hrbrmstr.png","language":"R","funding_links":["https://patreon.com/hrbrmstr"],"categories":["R","Plot layers","Graphic Displays","ggplot"],"sub_categories":["Miscellaneous"],"readme":"---\noutput: rmarkdown::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(collapse=TRUE, comment=\"##\", fig.retina=2, fig.path = \"README_figs/README-\")\n```\n\n[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/0.1.0/active.svg)](http://www.repostatus.org/#active) \n[![Travis-CI Build Status](https://travis-ci.org/hrbrmstr/ggalt.svg?branch=master)](https://travis-ci.org/hrbrmstr/ggalt) \n[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/hrbrmstr/ggalt?branch=master\u0026svg=true)](https://ci.appveyor.com/project/hrbrmstr/ggalt) \n[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/ggalt)](https://CRAN.R-project.org/package=ggalt) \n![downloads](http://cranlogs.r-pkg.org/badges/grand-total/ggalt)\n\n`ggalt` : Extra Coordinate Systems, Geoms, Statistical Transformations, Scales \u0026 Fonts for 'ggplot2'\n\nA compendium of 'geoms', 'coords', 'stats', scales and fonts for 'ggplot2', including splines, 1d and 2d densities, univariate average shifted histograms, a new map coordinate system based on the 'PROJ.4'-library and the 'StateFace' open source font 'ProPublica'.\n\nThe following functions are implemented:\n\n- `geom_ubar` : Uniform width bar charts\n- `geom_horizon` : Horizon charts (modified from \u003chttps://github.com/AtherEnergy/ggTimeSeries\u003e)\n- `coord_proj` : Like `coord_map`, only better (prbly shld use this with `geom_cartogram` as `geom_map`'s new defaults are ugh)\n- `geom_xspline` : Connect control points/observations with an X-spline\n- `stat_xspline` : Connect control points/observations with an X-spline\n- `geom_bkde` :\tDisplay a smooth density estimate (uses `KernSmooth::bkde`)\n- `geom_stateface`:\tUse ProPublica's StateFace font in ggplot2 plots\n- `geom_bkde2d` : Contours from a 2d density estimate. (uses `KernSmooth::bkde2D`)\n- `stat_bkde` :\tDisplay a smooth density estimate (uses `KernSmooth::bkde`)\n- `stat_bkde2d` :\tContours from a 2d density estimate. (uses `KernSmooth::bkde2D`)\n- `stat_ash` : Compute and display a univariate averaged shifted histogram (polynomial kernel) (uses `ash::ash1`/`ash::bin1`)\n- `geom_encircle`:\tAutomatically enclose points in a polygon\n- `byte_format`: + helpers. e.g. turn `10000` into `10 Kb`\n- `geom_lollipop()`: Dead easy lollipops (horizontal or vertical)\n- `geom_dumbbell()` : Dead easy dumbbell plots\n- `stat_stepribbon()` : Step ribbons\n- `annotation_ticks()` : Add minor ticks to identity, exp(1) and exp(10) axis scales independently of each other.\n- `geom_spikelines()` : Instead of geom_vline and geom_hline a pair of segments that originate from same c(x,y) are drawn to the respective axes.\n\n- plotly integration for a few of the ^^ geoms\n\n### Installation\n\n```{r eval=FALSE}\n# you'll want to see the vignettes, trust me\ninstall.packages(\"ggplot2\")\ninstall.packages(\"ggalt\")\n# OR: devtools::install_github(\"hrbrmstr/ggalt\")\n```\n\n```{r echo=FALSE, message=FALSE, warning=FALSE, error=FALSE}\noptions(width=120)\n```\n\n### Usage\n\n```{r}\nlibrary(ggplot2)\nlibrary(gridExtra)\nlibrary(ggalt)\n\n# current verison\npackageVersion(\"ggalt\")\n\nset.seed(1492)\ndat \u003c- data.frame(x=c(1:10, 1:10, 1:10),\n                  y=c(sample(15:30, 10), 2*sample(15:30, 10), 3*sample(15:30, 10)),\n                  group=factor(c(rep(1, 10), rep(2, 10), rep(3, 10)))\n)\n```\n\n### Horzon Chart\n\nExample carved from: \u003chttps://github.com/halhen/viz-pub/blob/master/sports-time-of-day/2_gen_chart.R\u003e\n\n```{r horizon, message=FALSE, warning=FALSE, fig.height=9.5, fig.width=9.5}\nlibrary(hrbrthemes)\nlibrary(ggalt)\nlibrary(tidyverse)\n\nsports \u003c- read_tsv(\"https://github.com/halhen/viz-pub/raw/master/sports-time-of-day/activity.tsv\")\n\nsports %\u003e%\n  group_by(activity) %\u003e% \n  filter(max(p) \u003e 3e-04, \n         !grepl('n\\\\.e\\\\.c', activity)) %\u003e% \n  arrange(time) %\u003e%\n  mutate(p_peak = p / max(p), \n         p_smooth = (lag(p_peak) + p_peak + lead(p_peak)) / 3,\n         p_smooth = coalesce(p_smooth, p_peak)) %\u003e% \n  ungroup() %\u003e%\n  do({ \n    rbind(.,\n          filter(., time == 0) %\u003e%\n            mutate(time = 24*60))\n  }) %\u003e%\n  mutate(time = ifelse(time \u003c 3 * 60, time + 24 * 60, time)) %\u003e%\n  mutate(activity = reorder(activity, p_peak, FUN=which.max)) %\u003e% \n  arrange(activity) %\u003e%\n  mutate(activity.f = reorder(as.character(activity), desc(activity))) -\u003e sports\n\nsports \u003c- mutate(sports, time2 = time/60)\n\nggplot(sports, aes(time2, p_smooth)) +\n  geom_horizon(bandwidth=0.1) +\n  facet_grid(activity.f~.) +\n  scale_x_continuous(expand=c(0,0), breaks=seq(from = 3, to = 27, by = 3), labels = function(x) {sprintf(\"%02d:00\", as.integer(x %% 24))}) +\n  viridis::scale_fill_viridis(name = \"Activity relative to peak\", discrete=TRUE,\n                              labels=scales::percent(seq(0, 1, 0.1)+0.1)) +\n  labs(x=NULL, y=NULL, title=\"Peak time of day for sports and leisure\",\n       subtitle=\"Number of participants throughout the day compared to peak popularity.\\nNote the morning-and-evening everyday workouts, the midday hobbies,\\nand the evenings/late nights out.\") +\n  theme_ipsum_rc(grid=\"\") +\n  theme(panel.spacing.y=unit(-0.05, \"lines\")) +\n  theme(strip.text.y = element_text(hjust=0, angle=360)) +\n  theme(axis.text.y=element_blank())\n```\n\n### Splines!\n\n```{r splines}\nggplot(dat, aes(x, y, group=group, color=group)) +\n  geom_point() +\n  geom_line()\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point() +\n  geom_line() +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5)\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point(color=\"black\") +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5) +\n  geom_xspline(size=0.5)\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point(color=\"black\") +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5) +\n  geom_xspline(spline_shape=-0.4, size=0.5)\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point(color=\"black\") +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5) +\n  geom_xspline(spline_shape=0.4, size=0.5)\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point(color=\"black\") +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5) +\n  geom_xspline(spline_shape=1, size=0.5)\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point(color=\"black\") +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5) +\n  geom_xspline(spline_shape=0, size=0.5)\n\nggplot(dat, aes(x, y, group=group, color=factor(group))) +\n  geom_point(color=\"black\") +\n  geom_smooth(se=FALSE, linetype=\"dashed\", size=0.5) +\n  geom_xspline(spline_shape=-1, size=0.5)\n```\n\n#### Alternate (better) density plots\n\n```{r bkde_ash}\n# bkde\n\ndata(geyser, package=\"MASS\")\n\nggplot(geyser, aes(x=duration)) + \n  stat_bkde(alpha=1/2)\n\nggplot(geyser, aes(x=duration)) +\n  geom_bkde(alpha=1/2)\n\nggplot(geyser, aes(x=duration)) + \n  stat_bkde(bandwidth=0.25)\n\nggplot(geyser, aes(x=duration)) +\n  geom_bkde(bandwidth=0.25)\n\nset.seed(1492)\ndat \u003c- data.frame(cond = factor(rep(c(\"A\",\"B\"), each=200)), \n                   rating = c(rnorm(200),rnorm(200, mean=.8)))\n\nggplot(dat, aes(x=rating, color=cond)) + geom_bkde(fill=\"#00000000\")\n\nggplot(dat, aes(x=rating, fill=cond)) + geom_bkde(alpha=0.3)\n\n# ash\n\nset.seed(1492)\ndat \u003c- data.frame(x=rnorm(100))\ngrid.arrange(ggplot(dat, aes(x)) + stat_ash(),\n             ggplot(dat, aes(x)) + stat_bkde(),\n             ggplot(dat, aes(x)) + stat_density(),\n             nrow=3)\n\ncols \u003c- RColorBrewer::brewer.pal(3, \"Dark2\")\nggplot(dat, aes(x)) + \n  stat_ash(alpha=1/3, fill=cols[3]) + \n  stat_bkde(alpha=1/3, fill=cols[2]) + \n  stat_density(alpha=1/3, fill=cols[1]) + \n  geom_rug() +\n  labs(x=NULL, y=\"density/estimate\") +\n  scale_x_continuous(expand=c(0,0)) +\n  theme_bw() +\n  theme(panel.grid=element_blank()) +\n  theme(panel.border=element_blank())\n```\n\n### Alternate 2D density plots\n\n```{r bkde2d}\nm \u003c- ggplot(faithful, aes(x = eruptions, y = waiting)) +\n       geom_point() +\n       xlim(0.5, 6) +\n       ylim(40, 110)\n\nm + geom_bkde2d(bandwidth=c(0.5, 4))\n\nm + stat_bkde2d(bandwidth=c(0.5, 4), aes(fill = ..level..), geom = \"polygon\")\n\n```\n\n### `coord_proj` LIVES! (still needs a teensy bit of work)\n\n```{r coord_proj}\nworld \u003c- map_data(\"world\")\nworld \u003c- world[world$region != \"Antarctica\",]\n\ngg \u003c- ggplot()\ngg \u003c- gg + geom_cartogram(data=world, map=world,\n                    aes(x=long, y=lat, map_id=region))\ngg \u003c- gg + coord_proj(\"+proj=wintri\")\ngg\n```\n\n### ProPublica StateFace\n\n```{r stateface}\n# Run show_stateface() to see the location of the TTF StateFace font\n# You need to install it for it to work\n\nset.seed(1492)\ndat \u003c- data.frame(state=state.abb,\n                  x=sample(100, 50),\n                  y=sample(100, 50),\n                  col=sample(c(\"#b2182b\", \"#2166ac\"), 50, replace=TRUE),\n                  sz=sample(6:15, 50, replace=TRUE),\n                  stringsAsFactors=FALSE)\ngg \u003c- ggplot(dat, aes(x=x, y=y))\ngg \u003c- gg + geom_stateface(aes(label=state, color=col, size=sz))\ngg \u003c- gg + scale_color_identity()\ngg \u003c- gg + scale_size_identity()\ngg\n```\n\n### Encircling points automagically\n\n```{r encircle}\nd \u003c- data.frame(x=c(1,1,2),y=c(1,2,2)*100)\n\ngg \u003c- ggplot(d,aes(x,y))\ngg \u003c- gg + scale_x_continuous(expand=c(0.5,1))\ngg \u003c- gg + scale_y_continuous(expand=c(0.5,1))\n\ngg + geom_encircle(s_shape=1, expand=0) + geom_point()\n\ngg + geom_encircle(s_shape=1, expand=0.1, colour=\"red\") + geom_point()\n\ngg + geom_encircle(s_shape=0.5, expand=0.1, colour=\"purple\") + geom_point()\n\ngg + geom_encircle(data=subset(d, x==1), colour=\"blue\", spread=0.02) +\n  geom_point()\n\ngg +geom_encircle(data=subset(d, x==2), colour=\"cyan\", spread=0.04) + \n  geom_point()\n\ngg \u003c- ggplot(mpg, aes(displ, hwy))\ngg + geom_encircle(data=subset(mpg, hwy\u003e40)) + geom_point()\n\nss \u003c- subset(mpg,hwy\u003e31 \u0026 displ\u003c2)\n\ngg + geom_encircle(data=ss, colour=\"blue\", s_shape=0.9, expand=0.07) +\n  geom_point() + geom_point(data=ss, colour=\"blue\")\n```\n\n### Step ribbons\n\n```{r stepribbon}\nx \u003c- 1:10\ndf \u003c- data.frame(x=x, y=x+10, ymin=x+7, ymax=x+12)\n\ngg \u003c- ggplot(df, aes(x, y))\ngg \u003c- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax),\n                      stat=\"stepribbon\", fill=\"#b2b2b2\")\ngg \u003c- gg + geom_step(color=\"#2b2b2b\")\ngg\n\ngg \u003c- ggplot(df, aes(x, y))\ngg \u003c- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax),\n                      stat=\"stepribbon\", fill=\"#b2b2b2\",\n                      direction=\"vh\")\ngg \u003c- gg + geom_step(color=\"#2b2b2b\")\ngg\n```\n\n### Lollipop charts\n\n```{r lollipop}\ndf \u003c- read.csv(text=\"category,pct\nOther,0.09\nSouth Asian/South Asian Americans,0.12\nInterngenerational/Generational,0.21\nS Asian/Asian Americans,0.25\nMuslim Observance,0.29\nAfrica/Pan Africa/African Americans,0.34\nGender Equity,0.34\nDisability Advocacy,0.49\nEuropean/European Americans,0.52\nVeteran,0.54\nPacific Islander/Pacific Islander Americans,0.59\nNon-Traditional Students,0.61\nReligious Equity,0.64\nCaribbean/Caribbean Americans,0.67\nLatino/Latina,0.69\nMiddle Eastern Heritages and Traditions,0.73\nTrans-racial Adoptee/Parent,0.76\nLBGTQ/Ally,0.79\nMixed Race,0.80\nJewish Heritage/Observance,0.85\nInternational Students,0.87\", stringsAsFactors=FALSE, sep=\",\", header=TRUE)\n \nlibrary(ggplot2)\nlibrary(ggalt)\nlibrary(scales)\n \ngg \u003c- ggplot(df, aes(y=reorder(category, pct), x=pct))\ngg \u003c- gg + geom_lollipop(point.colour=\"steelblue\", point.size=2, horizontal=TRUE)\ngg \u003c- gg + scale_x_continuous(expand=c(0,0), labels=percent,\n                              breaks=seq(0, 1, by=0.2), limits=c(0, 1))\ngg \u003c- gg + labs(x=NULL, y=NULL, \n                title=\"SUNY Cortland Multicultural Alumni survey results\",\n                subtitle=\"Ranked by race, ethnicity, home land and orientation\\namong the top areas of concern\",\n                caption=\"Data from http://stephanieevergreen.com/lollipop/\")\ngg \u003c- gg + theme_minimal(base_family=\"Arial Narrow\")\ngg \u003c- gg + theme(panel.grid.major.y=element_blank())\ngg \u003c- gg + theme(panel.grid.minor=element_blank())\ngg \u003c- gg + theme(axis.line.y=element_line(color=\"#2b2b2b\", size=0.15))\ngg \u003c- gg + theme(axis.text.y=element_text(margin=margin(r=0, l=0)))\ngg \u003c- gg + theme(plot.margin=unit(rep(30, 4), \"pt\"))\ngg \u003c- gg + theme(plot.title=element_text(face=\"bold\"))\ngg \u003c- gg + theme(plot.subtitle=element_text(margin=margin(b=10)))\ngg \u003c- gg + theme(plot.caption=element_text(size=8, margin=margin(t=10)))\ngg\n```\n\n```{r dumbbell, message=FALSE}\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(scales)\nlibrary(ggplot2)\nlibrary(ggalt) # devtools::install_github(\"hrbrmstr/ggalt\")\n\nhealth \u003c- read.csv(\"https://rud.is/dl/zhealth.csv\", stringsAsFactors=FALSE, \n                   header=FALSE, col.names=c(\"pct\", \"area_id\"))\n\nareas \u003c- read.csv(\"https://rud.is/dl/zarea_trans.csv\", stringsAsFactors=FALSE, header=TRUE)\n\nhealth %\u003e% \n  mutate(area_id=trunc(area_id)) %\u003e% \n  arrange(area_id, pct) %\u003e% \n  mutate(year=rep(c(\"2014\", \"2013\"), 26),\n         pct=pct/100) %\u003e% \n  left_join(areas, \"area_id\") %\u003e% \n  mutate(area_name=factor(area_name, levels=unique(area_name))) -\u003e health\n\nsetNames(bind_cols(filter(health, year==2014), filter(health, year==2013))[,c(4,1,5)],\n         c(\"area_name\", \"pct_2014\", \"pct_2013\")) -\u003e health\n\ngg \u003c- ggplot(health, aes(x=pct_2014, xend=pct_2013, y=area_name, group=area_name))\ngg \u003c- gg + geom_dumbbell(colour=\"#a3c4dc\", size=1.5, colour_xend=\"#0e668b\", \n                         dot_guide=TRUE, dot_guide_size=0.15)\ngg \u003c- gg + scale_x_continuous(label=percent)\ngg \u003c- gg + labs(x=NULL, y=NULL)\ngg \u003c- gg + theme_bw()\ngg \u003c- gg + theme(plot.background=element_rect(fill=\"#f7f7f7\"))\ngg \u003c- gg + theme(panel.background=element_rect(fill=\"#f7f7f7\"))\ngg \u003c- gg + theme(panel.grid.minor=element_blank())\ngg \u003c- gg + theme(panel.grid.major.y=element_blank())\ngg \u003c- gg + theme(panel.grid.major.x=element_line())\ngg \u003c- gg + theme(axis.ticks=element_blank())\ngg \u003c- gg + theme(legend.position=\"top\")\ngg \u003c- gg + theme(panel.border=element_blank())\ngg\n```\n\n```{r dumbbell2, message=FALSE, fig.width=7, fig.height=2.5}\nlibrary(hrbrthemes)\n\ndf \u003c- data.frame(trt=LETTERS[1:5], l=c(20, 40, 10, 30, 50), r=c(70, 50, 30, 60, 80))\n\nggplot(df, aes(y=trt, x=l, xend=r)) + \n  geom_dumbbell(size=3, color=\"#e3e2e1\", \n                colour_x = \"#5b8124\", colour_xend = \"#bad744\",\n                dot_guide=TRUE, dot_guide_size=0.25) +\n  labs(x=NULL, y=NULL, title=\"ggplot2 geom_dumbbell with dot guide\") +\n  theme_ipsum_rc(grid=\"X\") +\n  theme(panel.grid.major.x=element_line(size=0.05))\n```\n\n```{r annoticks, message=FALSE, fig.width=7, fig.height=2.5}\np \u003c- ggplot(msleep, aes(bodywt, brainwt)) + geom_point()\n\n# add identity scale minor ticks on y axis\np + annotation_ticks(sides = 'l')\n\n# add identity scale minor ticks on x,y axis\np + annotation_ticks(sides = 'lb')\n\n# log10 scale\np1 \u003c- p + scale_x_log10()\n\n# add minor ticks on both scales\np1 + annotation_ticks(sides = 'lb', scale = c('identity','log10'))\n```\n\n```{r spikelines, message=FALSE, fig.width=7, fig.height=7}\n\nmtcars$name \u003c- rownames(mtcars)\n\np \u003c- ggplot(data = mtcars, aes(x=mpg,y=disp)) + geom_point()\n\np + \n  geom_spikelines(data = mtcars[mtcars$carb==4,],aes(colour = factor(gear)), linetype = 2) + \n  ggrepel::geom_label_repel(data = mtcars[mtcars$carb==4,],aes(label = name))\n\n```\n\n### Code of Conduct\n\nPlease note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). \nBy participating in this project you agree to abide by its terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhrbrmstr%2Fggalt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhrbrmstr%2Fggalt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhrbrmstr%2Fggalt/lists"}