0

I can successfully assign color to one factor (sex) levels. But I cannot figure out how to also assign shape to other factor (age_cat) levels and add a second legend at the desired location. I tried adding 'shape=age_cat' at various locations... But whatever I tried, distorts the plot!

My sample data, code and plot are below.

df = data.frame(sex = c(1,1,1,1,1, 2,2,2,2,2),
                age_cat = c(1,1,1, 2,2,2,  1,1,1, 2),
                score_type = c(1,2, 1,2, 1,2, 1,2, 1,2),
                score = c(25,28,18,20,30, 37,40,35,43,45))

df$sex <- factor((df$sex))
df$age_cat <- factor((df$age_cat))
df$score_type <- factor((df$score_type))

windows(width=7, height=7 )

df %>%
  ggplot( aes(x=score_type, y=score)) +
  geom_boxplot(aes(color=sex),outlier.shape = NA, size=1.5, show.legend = F) +
  geom_point(aes(color=sex), position=position_jitterdodge(dodge.width=0.9), size=3) +
  scale_color_manual(values=c("#0072B2", "#CC79A7"), name="", labels=c("Male", "Female")) +
  
  scale_shape_manual(name="", labels=c('Younger', 'Older'), values=c(1, 17)) +   # ??? How to assign shape ???
  
  theme_bw()+
  theme(panel.border = element_blank(), axis.ticks = element_blank(),
        legend.position=c(0.9, 0.65), legend.text=element_text(size=11), legend.title=element_text(size=11.5),
        panel.grid.major.x = element_blank() ,
        plot.title = element_text(size=11, face = "bold"), axis.title=element_text(size=13),
        axis.text.y = element_text(size=11),
        axis.text.x = element_text(size=11),
        plot.margin = unit(c(0.5,0.2,0,0.2), "cm")) +
  
  labs(title= "", x = "",y = "Score") +
  scale_y_continuous(breaks=c(0, 20, 40, 60, 80, 100), labels=c('0', '20', '40', '60', '80', '100')) +
  expand_limits(x=5, y=70) +
  scale_x_discrete(labels = c("A", "B")) + 
 
  coord_cartesian(clip = "off")

enter image description here

2
  • 1
    Maybe you clarify what you mean by "... distorts the plot!"? If you want to have different shape without affecting how the points are dodged you could do geom_point(aes(color = sex, shape = age_cat, group = sex). Commented Jan 12, 2022 at 23:10
  • This helps! Data points from factor sex remain within the boundaries of the boxplots where they should belong (the plot is not distorted). Commented Jan 12, 2022 at 23:54

1 Answer 1

1

You only need to specify shape = age_cat and group = sex in the aestetics of geom_point.

library(purrr)
library(ggplot2)

df %>%
  ggplot( aes(x=score_type, y=score)) +
  geom_boxplot(aes(color=sex),outlier.shape = NA, size=1.5, show.legend = F) +
  geom_point(aes(color=sex, shape = age_cat, group = sex),
 position=position_jitterdodge(dodge.width=0.9), size=3) +
  scale_color_manual(values=c("#0072B2", "#CC79A7"), name="",
 labels=c("Male", "Female")) +
  scale_shape_manual(name="", labels=c('Younger', 'Older'),
values=c(1, 17)) +
  theme_bw()+
  theme(panel.border = element_blank(), axis.ticks = element_blank(),
        legend.position=c(0.9, 0.65), legend.text=element_text(size=11),
 legend.title=element_text(size=11.5),
        panel.grid.major.x = element_blank() ,
        plot.title = element_text(size=11, face = "bold"),
 axis.title=element_text(size=13),
        axis.text.y = element_text(size=11),
        axis.text.x = element_text(size=11),
        plot.margin = unit(c(0.5,0.2,0,0.2), "cm")) +
  labs(title= "", x = "",y = "Score") +
  scale_y_continuous(breaks=c(0, 20, 40, 60, 80, 100),
labels=c('0', '20', '40', '60', '80', '100')) +
  expand_limits(x=5, y=70) +
  scale_x_discrete(labels = c("A", "B")) + 
  coord_cartesian(clip = "off")

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

shape = age_cat in the aesthetics of geom_point is not enough, unfortunately. Data points from factor sex go outside the borders of the boxplots where they should belong... I much abbreviated my original data set for the question, so this is on easily visible.
I see, but you did not specify this in your question. I edited the answer accordingly. It should now match your aim. Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.