rggplot2colorsfacetcolorbrewer

How can I change the colour of each facet map?


I am plotting survey data (ESS) on party preference using ggplot and am creating a separate facet plot for each party. I would like each plot to have the colour of the party it is showing, wherein darker colours means more votes.

Here's what my data looks like

head(party_votes_summary)

# A tibble: 5 × 7
# Groups:   NUTS_NAME [5]
  NUTS_NAME   all_votes    total_votes                  geometry percentage_votes                geometry.y
  <chr>       <fct>              <int>        <MULTIPOLYGON [m]>            <dbl>        <MULTIPOLYGON [m]>
1 Centro (IT) Forza Italia          18 (((4358646 2346312, 4371…          0.0111  (((4358646 2346312, 4371…
2 Isole       Fratelli d'…           0 (((4787072 1652570, 4774…         NA                           EMPTY
3 Nord-Est    Altro                 34 (((4510729 2621661, 4527…          0.0209  (((4510729 2621661, 4527…
4 Nord-Ovest  Forza Italia          37 (((4386364 2524813, 4371…          0.0228  (((4386364 2524813, 4371…
5 Sud         Fratelli d'…          16 (((4945372 2007501, 4997…          0.00984 (((4945372 2007501, 4997…
# ℹ 1 more variable: NUTS_ID <chr>

Currently, I have this code

ggplot(party_votes_summary) +
  geom_sf(aes(fill = total_votes, geometry = geometry), color = "black") +
  facet_wrap(~ all_votes, labeller = labeller(all_votes = c(
    "Partido Democratico (PD)" = "Partido Democratico",
    "Sinistra Ecologia e Libertà (SEL)" = "Sinistra Ecologia e Libertà",
    "Popolo delle Libertà (PdL)" = "Popolo delle Libertà"
    ))) +
  labs(title = "Summary of Votes per Party per Region",
       fill = "Party") +
  theme(axis.text.x = element_blank(),  
        axis.text.y = element_blank(),  
        axis.ticks = element_blank())+
  scale_fill_distiller(palette = "Blues", direction = 1) 

Which produces this plot:

My current plot

As I mentioned, I would like each facet to be a different colour, darker for more votes and ligther for less.

This is the code for my plot

ggplot(party_votes_summary) +
  geom_sf(aes(fill = total_votes, geometry = geometry), color = "black") +
  facet_wrap(~ all_votes, labeller = labeller(all_votes = c(
    "Partido Democratico (PD)" = "Partido Democratico",
    "Sinistra Ecologia e Libertà (SEL)" = "Sinistra Ecologia e Libertà",
    "Popolo delle Libertà (PdL)" = "Popolo delle Libertà"
    ))) +
  labs(title = "Summary of Votes per Party per Region",
       fill = "Party") +
  theme(axis.text.x = element_blank(),  
        axis.text.y = element_blank(),  
        axis.ticks = element_blank())+
  scale_fill_manual(values = party_palette)

And the error I get is:

Error in scale_fill_manual(): ! Continuous values supplied to discrete scale. ℹ Example values: 261, 261, 261, 261, and 261

I have tried with both of these colour vectors:

party_colours <- c("Movimento 5 Stelle" = "#EED924",
"Lega" = "#008000",
"Partido Democratico (PD)" = "#DC143C",
"Forza Italia" = "#0087DC",
"Fratelli d'Italia" = "darkblue",
"SVP-PATT"="#8a8a8a",
"+ Europa" = "darkgreen",
"Altro"="whitesmoke",
"Sinistra Ecologia e Libertà (SEL)"="palegreen2",
"Liberi e Uguali" = "darkred",
"Popolo delle Libertà (PdL)" = "#0099DC",
"La Destra" = "royalblue")

party_palette <- c(
"Movimento 5 Stelle" = scale_fill_brewer(palette = "OrRd"),
"Lega" = scale_fill_brewer(palette = "Greens"),
"Partido Democratico (PD)" = scale_fill_brewer(palette = "Reds"),
"Forza Italia" = scale_fill_brewer(palette = "Blues"),
"Fratelli d'Italia" = scale_fill_brewer(palette = "Blues"),
"SVP-PATT" = scale_fill_brewer(palette = "Greys"),
"+ Europa" = scale_fill_brewer(palette = "Greens"),
"Altro" = scale_fill_brewer(palette = "Greys"),
"Sinistra Ecologia e Libertà (SEL)" = scale_fill_brewer(palette = "Greens"),
"Liberi e Uguali" = scale_fill_brewer(palette = "Reds"),
"Popolo delle Libertà (PdL)" = scale_fill_brewer(palette = "Blues"),
"La Destra" = scale_fill_brewer(palette = "Blues"))

Any help is greatly appreciated!! And let me know if you need anything else to understand my data/code better :)

Session info:

R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.3

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] ISCO08ConveRsions_0.2.0 nuts_1.0.0              leaflet_2.2.1          
 [4] cowplot_1.1.3           stargazer_5.2.3         knitr_1.45             
 [7] huxtable_5.5.6          data.table_1.15.2       countrycode_1.5.0      
[10] profvis_0.3.8           RColorBrewer_1.1-3      ggspatial_1.1.9        
[13] ggrepel_0.9.5           viridis_0.6.5           viridisLite_0.4.2      
[16] reshape2_1.4.4          see_0.8.2               MASS_7.3-60.0.1        
[19] nnet_7.3-19             tictoc_1.2              vdemdata_13.0          
[22] readxl_1.4.3            haven_2.5.4             raster_3.6-26          
[25] sp_2.1-3                modelsummary_1.4.5      tidytext_0.4.1         
[28] themis_1.0.2            textrecipes_1.0.6       rpart.plot_3.1.2       
[31] rattle_5.5.1            bitops_1.0-7            ranger_0.16.0          
[34] parttree_0.0.1.9004     plotly_4.10.4           pscl_1.5.9             
[37] texreg_1.39.3           rpart_4.1.23            sjPlot_2.8.15          
[40] randomForest_4.7-1.1    gghighlight_0.4.1       ggeffects_1.5.0        
[43] ggiraphExtra_0.3.0      sf_1.0-15               yardstick_1.3.0        
[46] workflowsets_1.0.1      workflows_1.1.4         tune_1.1.2             
[49] rsample_1.2.0           recipes_1.0.10          parsnip_1.2.0          
[52] modeldata_1.3.0         infer_1.0.6             dials_1.2.1            
[55] scales_1.3.0            broom_1.0.5             tidymodels_1.1.1       
[58] patchwork_1.2.0         readstata13_0.10.1      brant_0.3-0            
[61] janitor_2.2.0           gtsummary_1.7.2         gt_0.10.1              
[64] vip_0.4.1               lubridate_1.9.3         forcats_1.0.0          
[67] stringr_1.5.1           dplyr_1.1.4             purrr_1.0.2            
[70] readr_2.1.5             tidyr_1.3.1             tibble_3.2.1           
[73] ggplot2_3.5.0           tidyverse_2.0.0        

loaded via a namespace (and not attached):
  [1] splines_4.3.2        cellranger_1.1.0     datawizard_0.9.1     hardhat_1.3.1       
  [5] lifecycle_1.0.4      globals_0.16.2       lattice_0.22-5       insight_0.19.8      
  [9] crosstalk_1.2.1      SnowballC_0.7.1      backports_1.4.1      magrittr_2.0.3      
 [13] sass_0.4.8           rmarkdown_2.26       jquerylib_0.1.4      yaml_2.3.8          
 [17] DBI_1.2.2            minqa_1.2.6          ipred_0.9-14         lava_1.8.0          
 [21] tokenizers_0.3.0     listenv_0.9.1        terra_1.7-71         units_0.8-5         
 [25] performance_0.10.9   parallelly_1.37.1    svglite_2.1.3        codetools_0.2-19    
 [29] xml2_1.3.6           tidyselect_1.2.0     farver_2.1.1         effectsize_0.8.6    
 [33] lme4_1.1-35.1        broom.helpers_1.14.0 jsonlite_1.8.8       e1071_1.7-14        
 [37] survival_3.5-8       iterators_1.0.14     emmeans_1.10.0       systemfonts_1.0.5   
 [41] foreach_1.5.2        tools_4.3.2          Rcpp_1.0.12          glue_1.7.0          
 [45] gridExtra_2.3        prodlim_2023.08.28   xfun_0.42            mgcv_1.9-1          
 [49] withr_3.0.0          ROSE_0.0-4           fastmap_1.1.1        boot_1.3-30         
 [53] fansi_1.0.6          digest_0.6.34        timechange_0.3.0     R6_2.5.1            
 [57] estimability_1.5     colorspace_2.1-0     utf8_1.2.4           generics_0.1.3      
 [61] class_7.3-22         httr_1.4.7           htmlwidgets_1.6.4    parameters_0.21.5   
 [65] pkgconfig_2.0.3      gtable_0.3.4         timeDate_4032.109    lmtest_0.9-40       
 [69] GPfit_1.0-8          furrr_0.3.1          janeaustenr_1.0.0    htmltools_0.5.7     
 [73] mycor_0.1.1          kableExtra_1.4.0     gower_1.0.1          snakecase_0.11.1    
 [77] rstudioapi_0.15.0    tzdb_0.4.0           uuid_1.2-0           checkmate_2.3.1     
 [81] nlme_3.1-164         nloptr_2.0.3         cachem_1.0.8         zoo_1.8-12          
 [85] proxy_0.4-27         sjlabelled_1.2.0     KernSmooth_2.23-22   parallel_4.3.2      
 [89] pillar_1.9.0         grid_4.3.2           vctrs_0.6.5          xtable_1.8-4        
 [93] lhs_1.1.6            evaluate_0.23        mvtnorm_1.2-4        cli_3.6.2           
 [97] compiler_4.3.2       crayon_1.5.2         rlang_1.1.3          ppcor_1.1           
[101] future.apply_1.11.1  labeling_0.4.3       modelr_0.1.11        classInt_0.4-10     
[105] plyr_1.8.9           sjmisc_2.8.9         ggiraph_0.8.9        stringi_1.8.3       
[109] assertthat_0.2.1     tables_0.9.17        munsell_0.5.0        lazyeval_0.2.2      
[113] bayestestR_0.13.2    pacman_0.5.1         Matrix_1.6-5         sjstats_0.18.2      
[117] hms_1.1.3            future_1.33.1        highr_0.10           bslib_0.6.1         
[121] DiceDesign_1.10   

Solution

  • This is what eneded up working for me. Wish there was an easier way, but it gets the job done:

    # Define custom color gradients for each party
    party_palette <- list(
      "Movimento 5 Stelle" = colorRampPalette(c("#FF4500", "#FFE4B5"))(10),  # Orange gradient
      "Lega" = colorRampPalette(c("#006400", "#98FB98"))(10),                # Green gradient
      "Partido Democratico (PD)" = colorRampPalette(c("#8B0000", "#FFC0CB"))(10),  # Red gradient
      "Forza Italia" = colorRampPalette(c("#87CEFA", "#00008B"))(10),         # Blue gradient
      "Fratelli d'Italia" = colorRampPalette(c("#87CEFA", "#00008B"))(10),    # Blue gradient
      "SVP-PATT" = colorRampPalette(c("#DCDCDC", "#A9A9A9"))(10),             # Grey gradient
      "Altro" = colorRampPalette(c("#DCDCDC", "#A9A9A9"))(10),                 # Grey gradient
      "Sinistra Ecologia e Libertà (SEL)" = colorRampPalette(c("#006400", "#98FB98"))(10),  # Green gradient
      "Liberi e Uguali" = colorRampPalette(c("#8B0000", "#FFC0CB"))(10),      # Red gradient
      "Popolo delle Libertà (PdL)" = colorRampPalette(c("#87CEFA", "#00008B"))(10),         # Blue gradient
      "La destra" = colorRampPalette(c("#87CEFA", "#00008B"))(10)              # Blue gradient
    )
    
    
    # Function to create gradient plots for each party
    create_party_plot <- function(party_name, party_palette) {
      ggplot(party_votes_summary[party_votes_summary$all_votes == party_name, ]) +
        geom_sf(aes(fill = total_votes, geometry = geometry), color = "darkgrey") +
        scale_fill_gradientn(colors = party_palette[[party_name]], name = "Votes") +
        labs(title = paste(party_name),
             fill = "Votes") +
        theme(axis.text.x = element_blank(),  
              axis.text.y = element_blank(),  
              axis.ticks = element_blank(),
              plot.title = element_text(hjust = 0.5),
              legend.position = "none") +
        coord_sf(crs = st_crs(3035))  
    }
    
    # Create separate plots for each party
    party_plots <- lapply(names(party_palette), function(party_name) {
      create_party_plot(party_name, party_palette)
    })
    
    grid.arrange(
      grobs = lapply(party_plots, function(plot) {
        plot + coord_sf(lims_method = "geometry_bbox")
      }),
      ncol = 4,  # Adjust the number of columns as needed
      top = "Party Votes by Region"
    )
    

    It produces this plot: this plot