1

Is there a way to plot the two counties side by side (without changing actual scale) to compare their sizes.

I wish to plot San Diego and Santa Clara side by side to demonstrate their actual size.

Thanks

library(tigris)
library(ggplot2)

san_diego <- county_subdivisions(state = "CA", county = "San Diego County", cb = TRUE, year = NULL)

santa_clara <- county_subdivisions(state = "CA", county = "Santa Clara County", cb = TRUE, year = NULL)


gg_san_diego <- ggplot() + 
  geom_sf(data = san_diego, 
          color="black",
          fill="white", 
          size=0.25)

gg_santa_clara <- ggplot() + 
  geom_sf(data = santa_clara, 
          color="black",
          fill="white", 
          size=0.25)


gg_san_diego

gg_santa_clara

phalteman
  • 3,442
  • 1
  • 29
  • 46
SiH
  • 1,378
  • 4
  • 18

3 Answers3

6

A straightforward way to do this is to move the counties to the same location by subtracting their centroids, then faceting by county name. Here's a fully reproducible example:

library(tigris)
library(tidyverse)
library(sf)

county_subdivisions(state = "CA", cb = TRUE, year = NULL,
                    county = c("San Diego County", "Santa Clara County")) %>%
  group_by(NAMELSADCO) %>%
  mutate(geometry = geometry - st_centroid(st_union(geometry))) %>%
  ggplot() + 
  geom_sf(color = "black", fill = "white") +
  facet_wrap(.~NAMELSADCO) +
  theme_void(base_size = 20) +
  theme(strip.text = element_text(margin = margin(20, 20, 20, 20)),
        panel.background = element_rect(fill = "gray95", color = NA))

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Wow, thanks. That sounds a like a good idea. Can we use tmap and make it to a publishable quality. – SiH Aug 10 '23 at 22:39
  • 4
    DONT use this for precise comparisons of polygons. Adding constants to the coordinates of spatial objects with coordinate systems is not very geographically meaningful within the coordinate system - for example you can't add 50N to 50N. `sf` will do the addition but remove the coordinate system so you get a point at "100" with no coordinate system metadata. Shifting things this way may then result in distortions. Really you need to do a rotation in spherical coordinates to move two features closer together. – Spacedman Aug 11 '23 at 13:21
  • 1
    @Spacedman fair point, and of course this is true in general, but for this specific case (side-by-side visual comparison of relatively small geographic areas from similar latitudes), I don't think there is sufficient distortion to make a meaningful difference to the final output graphic. I may be wrong about this though, and If you had time to demonstrate a way to rotate an sf object in spherical co-ordinates that gave a more accurate output, I would be very grateful. – Allan Cameron Aug 11 '23 at 14:02
  • 2
    I think you could project each item to an azimuthal coordinate system centred on the item centroid... For absolute precision you'd need to compute the original spherical areas and make sure the projected areas are to the same ratio... But I thought this needed a slight warning before Greenland becomes bigger than Africa again... – Spacedman Aug 11 '23 at 15:28
  • Thanks @Spacedman and @ Allan Cameron. Can I compare the true size of Sydney, Japan, London and New York by plotting side by side. Do I need to worry about the distortions. – SiH Aug 21 '23 at 17:46
3

One solution is to obtain the centroids of the two objects and set the limits of both plots by the same value (i.e., a constant), using coord_sf. Then, you can put both plots side by side using patchwork.

library(tigris)
library(ggplot2)
library(sf)
library(dplyr)
library(patchwork)

# Constant to sum and subtract from centroid
# to set limits of the plots
constant <- 1

# Calculate centroids for both objects
centroidSD <- san_diego |>
  summarize() |>
  st_centroid() |>
  st_coordinates() |>
  as_tibble()

centroidSC <- santa_clara |>
  summarize() |>
  st_centroid()|>
  st_coordinates() |>
  as_tibble()

# Makes both plots and set x and y limits according to 
# centroid and + / - constant
gg_san_diego <- ggplot() + 
  geom_sf(data = san_diego, 
          color="black",
          fill="white", 
          size=0.25) + 
  coord_sf(xlim = c(centroidSD$X - constant,
                    centroidSD$X + constant),
           ylim = c(centroidSD$Y - constant,
                    centroidSD$Y + constant))

gg_santa_clara <- ggplot() + 
  geom_sf(data = santa_clara, 
          color="black",
          fill="white", 
          size=0.25) + 
  coord_sf(xlim = c(centroidSC$X - constant,
                    centroidSC$X + constant),
           ylim = c(centroidSC$Y - constant,
                    centroidSC$Y + constant))

# Use patchowrk to put both plots side by side
gg_san_diego + gg_santa_clara

twoplots

1

is this the expected result


combined_data <- rbind(
  data.frame(County = "San Diego", geometry = san_diego$geometry),
  data.frame(County = "Santa Clara", geometry = santa_clara$geometry)
)

ggplot(combined_data, aes(geometry = geometry, fill = County)) +
  geom_sf(color = "black") +
  scale_fill_manual(values = c("blue", "red")) +
  labs(title = "San Diego County vs. Santa Clara County", fill = "County") +
  theme(legend.position = "right")

enter image description here

jkatam
  • 2,691
  • 1
  • 4
  • 12
  • Thanks @jkatam for trying. Yes, it makes send. However, is there a way to move San Diego closer to Santa Clara without distorting the scale. Suppose, I want to compare a county in New York with a county in California. Your suggested solution may not help in that case. – SiH Aug 10 '23 at 21:58
  • in that case its better to plot the two separately instead of 1 plot , create 2 plots and keep them side by side , we cannot change – jkatam Aug 10 '23 at 22:10