Home > front end >  Color and fill geom_point by group and combine legend
Color and fill geom_point by group and combine legend

Time:07-07

I am having difficulty customising the ggplot (geom_point) output.

  1. Points to have black outline but with different fill colors by group (white and black)
  2. Is there a way to combine the legend into one?

Data

library(dplyr)
library(ggplot2)

dat <- structure(list(q = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L), 
    is_female = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
    2L), levels = c("Male", "Female"), class = "factor"), mean_exp = c(19.3095475534936, 
    19.2351713991988, 21.6718804471611, 21.69517120871, 23.4144749290445, 
    23.4191383190372, 25.2817658487443, 25.2772340355605, 28.3982168611512, 
    28.7869521340185), mean_fi = c(0.0915386254018914, 0.0912295567094683, 
    0.0771055282779973, 0.0790597510143077, 0.0859508568981647, 
    0.088489590940481, 0.109848283385112, 0.11358904634185, 0.128425331060705, 
    0.136830729164909), b_fi.frail = c(1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1), pct = c(47.5830407777478, 52.4169592222522, 37.567084078712, 
    62.432915921288, 36.9897959183673, 63.0102040816327, 34.0960360941025, 
    65.9039639058975, 29.0891283055828, 70.9108716944172)), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -10L), groups = structure(list(
    q = 1:5, .rows = structure(list(1:2, 3:4, 5:6, 7:8, 9:10), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -5L), .drop = TRUE))

My attempt:

ggplot(dat, aes(x=mean_exp, y=mean_fi, linetype=is_female))  
  geom_point(aes(color=is_female, fill=is_female), size=2, shape="square")  
  geom_line()  
  scale_x_continuous(limits = c(18, 30), breaks = seq(20, 30, 5), expand = c(0,0))  
  scale_y_continuous(limits = c(0.05, 0.15), breaks = seq(0.05, 0.15, 0.02), expand = c(0,0))  
  scale_color_manual(values = c("M" = "black", "F" = "black"))  
  scale_fill_manual(values = c("M" = "black", "F" = "white"))  
  labs(x= expression(Body ~ mass ~ index ~ (kg/m^2)), y= "Mean baseline FI score", title = "BMI")  
  theme_classic()  
  theme(plot.title = element_text(hjust=0.5),
        legend.position = "bottom")

My code outputs a graph with grey points and lines for some reason. I would like black lines and outlines (but points to be filled with black or white depending on the group) and to combine the legend if possible.

I realise there are many similar examples out there but I can't seem to figure out why my code is not working... Thanks for your help in advance!

enter image description here

CodePudding user response:

Use shape = 22 for a fillable square, i.e. one which can have a different outline.

Colour can be outside the aes if both groups require a black outline for the points.

library(dplyr)
library(ggplot2)

dat <- structure(list(
  q = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L),
  is_female = structure(c(
    1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L,
    2L
  ), levels = c("Male", "Female"), class = "factor"), mean_exp = c(
    19.3095475534936,
    19.2351713991988, 21.6718804471611, 21.69517120871, 23.4144749290445,
    23.4191383190372, 25.2817658487443, 25.2772340355605, 28.3982168611512,
    28.7869521340185
  ), mean_fi = c(
    0.0915386254018914, 0.0912295567094683,
    0.0771055282779973, 0.0790597510143077, 0.0859508568981647,
    0.088489590940481, 0.109848283385112, 0.11358904634185, 0.128425331060705,
    0.136830729164909
  ), b_fi.frail = c(
    1, 1, 1, 1, 1, 1, 1, 1,
    1, 1
  ), pct = c(
    47.5830407777478, 52.4169592222522, 37.567084078712,
    62.432915921288, 36.9897959183673, 63.0102040816327, 34.0960360941025,
    65.9039639058975, 29.0891283055828, 70.9108716944172
  )
), class = c(
  "grouped_df",
  "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -10L), groups = structure(list(
  q = 1:5, .rows = structure(list(1:2, 3:4, 5:6, 7:8, 9:10), ptype = integer(0), class = c(
    "vctrs_list_of",
    "vctrs_vctr", "list"
  ))
), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L), .drop = TRUE))
  
ggplot(dat, aes(x = mean_exp, y = mean_fi, linetype = is_female))  
  geom_point(aes(fill = is_female), size = 2, shape = 22, colour = "black")  
  geom_line()  
  scale_x_continuous(limits = c(18, 30), breaks = seq(20, 30, 5), expand = c(0, 0))  
  scale_y_continuous(limits = c(0.05, 0.15), breaks = seq(0.05, 0.15, 0.02), expand = c(0, 0))  
  scale_fill_manual(values = c("black", "white"))  
  labs(x = expression(Body ~ mass ~ index ~ (kg / m^2)), y = "Mean baseline FI score", 
       title = "BMI", fill = "Sex", linetype = "Sex")  
  theme_classic()  
  theme(
    plot.title = element_text(hjust = 0.5),
    legend.position = "bottom"
  )

Created on 2022-07-07 by the reprex package (v2.0.1)

  • Related