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:
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
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: