Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Color and fill geom_point by group and combine legend

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading