{"id":15893585,"url":"https://github.com/gl-li/ggtiger","last_synced_at":"2025-10-24T13:19:13.188Z","repository":{"id":161032478,"uuid":"123801296","full_name":"GL-Li/ggtiger","owner":"GL-Li","description":"Draw census boundaries and data on ggmap","archived":false,"fork":false,"pushed_at":"2020-08-02T13:40:32.000Z","size":16034,"stargazers_count":15,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-16T16:48:34.410Z","etag":null,"topics":["census","map","r","visualization"],"latest_commit_sha":null,"homepage":"","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/GL-Li.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-04T15:21:27.000Z","updated_at":"2024-08-24T12:39:57.000Z","dependencies_parsed_at":"2023-05-31T08:45:22.944Z","dependency_job_id":null,"html_url":"https://github.com/GL-Li/ggtiger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/GL-Li/ggtiger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GL-Li%2Fggtiger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GL-Li%2Fggtiger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GL-Li%2Fggtiger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GL-Li%2Fggtiger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GL-Li","download_url":"https://codeload.github.com/GL-Li/ggtiger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GL-Li%2Fggtiger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280801229,"owners_count":26393471,"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","status":"online","status_checked_at":"2025-10-24T02:00:06.418Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["census","map","r","visualization"],"created_at":"2024-10-06T08:12:07.245Z","updated_at":"2025-10-24T13:19:13.156Z","avatar_url":"https://github.com/GL-Li.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput:\n  md_document:\n    variant: markdown_github\n---\n\n\n```{r, echo = FALSE}\nknitr::opts_chunk$set(\n    collapse = TRUE,\n    comment = \"#\u003e\",\n    fig.path = \"README-\",\n    message = FALSE,\n    warning = FALSE,\n    eval = FALSE\n)\n```\n\n\n\n\n[![Build Status](https://travis-ci.org/GL-Li/ggtiger.svg?branch=master)](https://travis-ci.org/GL-Li/ggtiger)\n\n# Draw TIGER census boundaries and plot census data on ggmap\n\nThis package draws TIGER census boundaries on ggmap with a single function `geom_bounday()` and plot census data on map with `geom_census()`. As extensions to `ggplot2`, `geom_boundary()` and `geom_census()` work similarly to native ggplot2 `geom_xxxx()` functions.\n\nIt currently draws boundaries of states, counties, county subdivisions, tracts, block groups, zip code tabulation areas, and congressional districts. More geographies are being added.\n\nIt now plot census data of 2010 decennial census, 2015, 2016 ACS 5-year survey, and 2014, 2015, 2016 ACS 1-year survey.\n\n\n## Installation and setup\n\n```{r eval = FALSE}\ndevtools::install_github(\"GL-Li/ggtiger\")\n```\n\nFunction `geom_boundary()` dowloads TIGER shape files into R with package `tigris`. The data is further processed for plotting. If you want to speed up the plotting, save the processed data to your computer. Check with function `set_path_to_tiger()`. \n\nFunction `geom_census()` uses package `totalcensus` to process census data, which requires downloading census data to your computer. Follow the [instructions](https://github.com/GL-Li/totalcensus) to install and set up `totalcensus` package.\n\n## Examples\nBy default, `geom_boundary()` draws all boundaries of a geography in the view of a ggmap. We can also choose to draw only those boundaries in selected states, or in selected counties in a state within the map.\n\nSimilarly, `geom_census` plot all available data points in the map. We can also choose which states and area to plot.\n\n### New example: congressional district gerrymandering\nWhen Republicans or Demecrats are in charge, they tend to draw congressional disctricts boundaries to their favor. This can go very ugly, creating crazy boundaries by a practice called [gerrymandering](https://en.wikipedia.org/wiki/Gerrymandering). \n\nWe can visualize the gerrymandering easily with `ggtiger`. The figure below shows a few congressional districts near Philadelpia in Pennsylvania for 115th Congress, including the (in)famous [7th congressional district](https://en.wikipedia.org/wiki/Pennsylvania%27s_7th_congressional_district).\n\n```{r}\nlibrary(ggtiger)\nregister_google(Sys.getenv(\"GGMAP_GOOGLE_API_KEY\"))\nphilly \u003c- get_map(\"pottstown, PA,  usa\", zoom = 9, color = \"bw\")\nggmap(philly) +\n    geom_boundary(\"congressional district\", states = \"PA\",\n                  mapping = aes(fill = ..GEOID..),\n                  alpha = 0.7, color = \"red\", size = 0.3) +\n    scale_fill_brewer(palette = \"PuOr\")\n```\n\n![](figures/congressional_disctrict.png)\n\nEven better, with function `geom_census()`, we can plot demographics on the map. This function depends on package `totalcensus`. Please visit [this repo](https://github.com/GL-Li/totalcensus) to find out how to use it.\n\n```{r}\nlibrary(viridis)\nggmap(philly) +\n    # plot demographic at each census block as a point, sized by population\n    # and colored by ratio of white people\n    geom_census(\"decennial\", year = 2010, states = \"PA\",\n                table_contents = \"white = P0030002\",\n                summary_level = \"block\",\n                mapping = aes(color = ..white../..population..)) +\n    # draw congressional district boundaries\n    geom_boundary(\"congressional district\", states = \"PA\",\n                  fill = NA, color = \"red\", size = 0.2) +\n    scale_size_area(max_size = 1) +   \n    scale_color_viridis() +\n    guides(size = \"none\") +  \n    labs(color = \"ratio of\\nwhite\")\n```\n\n![](figures/congressional_disctrict_census.png)\n\n### Draw boundaries\nBoundaries of state, county, county subdivision, tract, and block group:\n```{r}\nlibrary(ggtiger)\nri \u003c- get_map(\"scituate, RI, united states\", zoom = 10, color = \"bw\")\nggmap(ri) +\n    # all tract boundaries in two counties in Rhode Island\n    geom_boundary(\"tract\", states = \"RI\", counties = c(\"providence\", \"washington\"),\n                  fill = NA, color = \"orange\", size = 0.2) +\n    # all county boundaries in the map\n    geom_boundary(\"county\", fill = NA, \n                  color = \"green\", size = 0.3) +\n    # all state boundaries in the map\n    geom_boundary(\"state\", fill = NA, linetype = \"dotted\", \n                  color = \"red\", size = 0.5)\n\n```\n\n![](figures/boundaries.png)\n\n Boundaries of ZCTA (zip code tabulation area, based on zip code): be aware that ZCTAs sometimes cross county boundaries and even state boundaries.\n```{r}\nggmap(ri) +\n    # all ZCTAs in or partially in two counties in Rhode Island\n    geom_boundary(\"zip code\", states = \"RI\", \n                  counties = c(\"providence\", \"washington\"),\n                  fill = \"blue\", alpha = 0.1, color = \"red\", size = 0.3) +\n    # all county boundaries in RI. \n    geom_boundary(\"county\", state = \"RI\", fill = NA, color = \"green\", \n                  size = 0.5, linetype = \"dotted\")\n\n```\n\n![](figures/zip_code.png)\n\n\n### Fill in boudaries\nWe can fill in boudaies using argument `data_fill` in `geom_boundary()`. This argument takes a data frame that has `GEOID` as the first column and fill-in values as the second or other columns. You can use argument `mapping = aes(fill = ..xxx..)` to specify the fill column. Remember to add two dots `..` before and after the column name. If the data frame is extracted using census packages such as `tidycensus` and `totalcensus`, it already has the `GEOID` column.\n\n```{r fig.width=12}\nlibrary(tidycensus)\ncensus_api_key(Sys.getenv(\"CENSUS_API_KEY\"))  # use your own census API key\n# get the median home value in Providence county, RI by tract\nhome_value \u003c- get_acs(\"tract\", \"B25077_001\", state = \"RI\", county = \"Providence\") \nhead(home_value, 3)\n#    GEOID       NAME                                               variable   estimate   moe\n#    \u003cchr\u003e       \u003cchr\u003e                                              \u003cchr\u003e         \u003cdbl\u003e \u003cdbl\u003e\n#  1 44007000101 Census Tract 1.01, Providence County, Rhode Island B25077_001   155000  9765\n#  2 44007000102 Census Tract 1.02, Providence County, Rhode Island B25077_001   154700 11819\n#  3 44007000200 Census Tract 2, Providence County, Rhode Island    B25077_001   134600 31087\n\nggmap(ri) +\n    geom_boundary(\"tract\", data_fill = home_value, \n                  mapping = aes(fill = ..estimate..),\n                  color = \"blue\", size = 0.1, alpha = 0.8) +\n    geom_boundary(\"state\", fill = NA, color = \"red\") +\n    scale_fill_gradient(na.value = NA, low = \"cyan\", high = \"orange\") +\n    labs(fill = \"home_value\")\n```\n\n![](figures/boundaries_with_fill.png)\n\n\n### Combine with point plot\nLet's look at the black community near South Bend, Indiana. We present the population at each census block as a point, sized with total population and colored with percentage of black population. On top of that, we draw the boundaries of census tract.\n\n```{r fig.width=12}\nlibrary(totalcensus)\nlibrary(magrittr)\nsb_black \u003c- read_decennial(\n    year = 2010,\n    states = \"IN\",\n    table_contents = \"black_popul = P0030003\",\n    areas = \"St. Joseph County, IN\",\n    summary_level = \"block\"\n) %\u003e% \n    .[population != 0] %\u003e%\n    # percentage of black population in each block\n    .[, black_pct := round(100 * black_popul / population, 2)] %\u003e%\n    .[order(black_pct)]\n\nsb \u003c- get_map(\"south bend, IN\", zoom = 13, color = \"bw\")\np \u003c- ggmap(sb) +\n    geom_point(data = sb_black, alpha = 0.8,\n               aes(lon, lat, size = population, color = black_pct)) +\n    geom_boundary(\"tract\", fill = NA, color = \"orange\", size = 0.5) +\n    scale_size_area(max_size = 15, breaks = c(10, 100, 200, 500, 4000)) +\n    scale_color_continuous(low = \"green\", high = \"red\") \np\n```\n\n![](figures/boundaries_with_point.png)\n\n\n```{r}\n# to zoom in\np +  coord_map(xlim = c(-86.26, -86.21), ylim = c(41.67, 41.7))\n```\n\n![](figures/boundaries_with_point_zoom.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgl-li%2Fggtiger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgl-li%2Fggtiger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgl-li%2Fggtiger/lists"}