0

I'm making a map and want to add rectangles with a horizontal color gradient (darkest color on the left, fading to white on the right). I initially made the rectangles with geom_rect the most similar examples I could find in other SO posts was using geom_tile with a variable fill. I tried that below by generating a dummy column newcol that just holds the difference between the xmax and xmin of the real data so that the fill gradient would vary from left to right in each rectangle, but as you can see below, the rectangles still don't have a gradient. Any ideas?

library(ggplot2)
library(sf)
library(rnaturalearth)
library(tidyverse)

states <- ne_states(country = c("United States of America","Canada"), returnclass = "sf")

rectangles <- data_frame(
  y = (35:44)+0.5, 
  xmin = c(-75.5, -75.770333, -75.683333, -75.916667, -74.613, -74.0315, 
           -71.916667, -70.666667, -70.466667, -68.4), 
  xmax = c(-74.8, -74.616667, -73.983333, -72.8, -69.216667, -66.416667, 
           -65.65, -65.675833, -66.516667, -66.721667)
)%>% 
  pivot_longer(cols = c(xmax, xmin), names_to="identity", values_to="x") %>% 
  group_by(y) %>% 
  mutate(meanx = mean(x),
         newcol = x - min(x)) 

ggplot(data = states) +
  geom_sf() +
  geom_tile(data = rectangles, aes(x=meanx, y=y, width=2, height=1, fill=newcol), color="black") +
  scale_fill_gradient(low="darkblue", high="white") +
  coord_sf(xlim = c(-80, -65), ylim = c(34, 45.5), expand = FALSE) +
  NULL

enter image description here

AFH
  • 665
  • 1
  • 9
  • 28
  • Dataframe `rectangles` has two values for every x/y position, the latter of which is always zero, so your color scale ranges from 0 to 0. Perhaps you meant `newcol = meanx - min(x)` instead of `newcol = x - min(x)`? Or do you actually want to have *each* rectangle filled with a gradient, then you could try ggpattern: https://coolbutuseless.github.io/package/ggpattern// – I_O Jun 09 '23 at 07:34
  • Why would the color scale range from 0 to 0 if there are two different x values for each y? I'm trying to get the fill to vary over those two x-values (which is shown in the color bar on the right of the map, just not in the rectangle fill itself). – AFH Jun 09 '23 at 20:00
  • Because `scale_fill_*` doesn't have a gradient option for rectangles (or other polygons at that). The latter of any two rectangles per x/y position overplots the earlier one with a fill of high = low = zero (check df "rectangles"). The legend, on the other hand, duly displays the range of values across all rectangles. If you do need a gradient per rectangle, this should be (only) possible with {ggpattern}. – I_O Jun 09 '23 at 20:14
  • I did find this example (now linked in the OP: https://stackoverflow.com/questions/20069660/r-gradient-fill-for-geom-rect-in-ggplot2) using `scale_fill_*` with `geom_tile` so I think it should be possible without `ggpattern`? – AFH Jun 09 '23 at 21:43
  • This example does not show a tile with a gradient fill. It does show a series of stacked narrow tiles, each with a slightly different but uniform fill, mimicking a gradient. To reproduce that effect, you need to create a series of adjacent west-to-east tiles, group them by y-position and *calculate* a separate west-east colour gradient per group. Aside: be aware of redundant visuals (here: longitude as position *and* color); https://en.wikipedia.org/wiki/Chartjunk – I_O Jun 10 '23 at 04:55

0 Answers0