John J.
John J.

Reputation: 1748

use geom_col to add a layer with a subset of data, while keeping columns at the same width

Here's a graph with one column per month.

library(tidyverse)
library(lubridate)

# convert sunspot.month TS (from datasets package) to tibble
df <- tibble(spots = as.matrix(sunspot.month)[,1], date = zoo::as.Date(time(sunspot.month))) %>%
  filter(year(date) > 1999)

ggplot(df, aes(date, spots)) +
  geom_col()

enter image description here

I want to make each November column red, so I tried this.

ggplot(df, aes(date, spots)) +
  geom_col() +
  geom_col(data = function(x){filter(x, month(date) == 11)},
           fill = "red")

enter image description here

The columns from the subsetted layer expand to fill the x-axis space for the entire year. But I want the column to occupy the identical amount of width as in the original, full layer.

Here is a hacky way of doing it.

ggplot(df, aes(date, spots)) +
  geom_col() +
  geom_col(data = function(x){filter(x, month(date) == 11)},
           fill = "red", width = 30)

enter image description here

This is basically the output that I want, but I'm looking for a solution that doesn't require manually setting the column width.

Upvotes: 1

Views: 33

Answers (2)

MrFlick
MrFlick

Reputation: 206411

An alternative hacky way to to do it would be to set the non month 11 values to NA rather than filtering them

ggplot(df, aes(date, spots)) +
  geom_col() + 
  geom_col(data = function(x){mutate(x, spots=if_else(month(date) == 11, spots, NA_real_))},
           fill = "red")

enter image description here

Upvotes: 1

stefan
stefan

Reputation: 125218

You could map your condition on the fill aes and set your colors via scale_fill_manual:

library(tidyverse)
library(lubridate)

# convert sunspot.month TS (from datasets package) to tibble
df <- tibble(spots = as.matrix(sunspot.month)[,1], date = zoo::as.Date(time(sunspot.month))) %>%
  filter(year(date) > 1999)

ggplot(df, aes(date, spots)) +
  geom_col(aes(fill = month(date) == 11)) +
  scale_fill_manual(values = c("grey50", "red")) +
  guides(fill = "none")

Upvotes: 2

Related Questions