Li Yupeng
Li Yupeng

Reputation: 846

scale_x_continuous(minor_breaks = ...) does not draw minor grid lines properly when using ggplot2 and geom_sf to draw a map

I want to add the minor gridlines and tickmarkers (Shorter sticks and without ticklabels) to my map plot, I used scale_x_continuous(minor_breaks = ....), but this didn't work. I've tried some of the methods here, but that didn't work either.

Does anyone know how to solve this problem?

Here is the code and output figure.

library("sf")
library("rnaturalearth")
library("tidyverse")

world <- ne_countries(scale = "medium", returnclass = "sf")
usa = filter(world,admin =="United States of America")

# Plot
ggplot() +
  geom_sf(data = usa, fill = "lightblue",color = "black",alpha=.9) +
  coord_sf(
    xlim = c(-119, -74),
    ylim = c(22, 51),
   default_crs = sf::st_crs(4326),
    crs = st_crs("ESRI:102003"),
    expand = TRUE,
    lims_method = "box",
    label_axes = list(
      bottom = "E", top = "E",
      left = "N", right = "N"
    )) +
  xlab(NULL) + ylab(NULL) +
  ### adding grid lines on the top
  geom_hline(yintercept = seq(0, 90, by=5), 
             color = "blue", linetype = "solid", size = 0.5) +
   scale_x_continuous(minor_breaks = seq(-170, 0, by = 10),
                     breaks = seq(-170, 0, by = 20)
                       )+
  theme_bw()+
  theme( 
    # panel.grid=element_blank(),
    plot.background = element_rect(fill = NA, color = NA),
    axis.text = element_text(size = 12 ),
    panel.background = element_rect(fill = "grey"),
    panel.grid = element_line(colour = 'blue', size = 0.5),
    axis.ticks.length=unit(.4, "cm"),
  )

The red parts are what I want. enter image description here

Upvotes: 0

Views: 429

Answers (1)

dieghernan
dieghernan

Reputation: 3412

A potential hack to this is to create the breaks on a sequence of 10 seq(-170, 0, by = 10) but labelling only the lines you want with a custom function:

library("sf")
library("rnaturalearth")
library("tidyverse")

world <- ne_countries(scale = "medium", returnclass = "sf")
usa <- filter(world, admin == "United States of America")

# This is the custom function, does not produce labels on 120, 100, etc.
label_fun <- function(x) {
  s <- lapply(x, function(y) {
    if ((y %in% seq(-160, 0, 20))) return("")
    y <- paste0(abs(y), "ºW")
    return(y)
  })
  unlist(s)
}

# Plot
ggplot() +
  geom_sf(data = usa, fill = "lightblue", color = "black", alpha = .9) +
  coord_sf(
    xlim = c(-119, -74),
    ylim = c(22, 51),
    default_crs = sf::st_crs(4326),
    crs = st_crs("ESRI:102003"),
    expand = TRUE,
    lims_method = "box",
    label_axes = list(
      bottom = "E", top = "E",
      left = "N", right = "N"
    )
  ) +
  xlab(NULL) +
  ylab(NULL) +
  ### adding grid lines on the top
  geom_hline(
    yintercept = seq(0, 90, by = 5),
    color = "blue", linetype = "solid", size = 0.5
  ) +
  scale_x_continuous(
   # Modify breaks
    breaks = seq(-170, 0, by = 10),
    # And labels
    labels = label_fun
  ) +
  theme_bw() +
  theme(
    # panel.grid=element_blank(),
    plot.background = element_rect(fill = NA, color = NA),
    axis.text = element_text(size = 12),
    panel.background = element_rect(fill = "grey"),
    panel.grid = element_line(colour = "blue", size = 0.5),
    axis.ticks.length = unit(.4, "cm"),
  )


enter image description here

Upvotes: 1

Related Questions