How to change the inside color (fill) of a subset of points with the same shape based on a second variable in ggplot2?

Viewed 859

I had a hard time to find how to change inside color of geom_point in combined regression plot but I couldn't do it using scale_color_manual()

For site F and F1 I want to have same shape and same outside color but the inside of "F" blanck and inside of "F1" grey

Here is my code and plot

mydata<-read.csv(choose.files(),header=T)
ggplot(mydata,aes(y=density,x=Do, color=color, shape=color,group=site))+geom_point(size=3.5)+
  stat_smooth(method="lm",se=FALSE)+
  scale_shape_manual(values=seq(0,8))+
  scale_y_log10()+
  scale_x_log10()+
  labs(x = "Do", y = bquote('density'~(No.m^-3)))+
  theme_classic()+
  theme(aspect.ratio=1)+
  theme(axis.title.x = element_text(color = 'black',face = 'bold',size = 18, hjust = 0.5))+
  theme(axis.text = font)+
  theme(axis.title.y = element_text(color = 'black',face = 'bold',size=25, hjust = 0.5))+theme(legend.title = element_text(size=8, color = "white"),legend.position=c(0.17, 0.20),

enter image description here

mydata

     site     Do      density     color
1     A  15.32500000 14.6254359     A
2     A   3.46153846  2.5634207     A
3     A   1.37692308 54.5375387     A
4     A   0.52115385 44.4123777     A
5     B   9.71431056  5.4299784     B
6     B   7.60803311  2.9582927     B
7     B   6.61874506  1.3994870     B
8     B   5.38889098  2.1169919     B
9     C  18.95522388  0.6911765     C
10    C  12.23880597  1.2352941     C
11    C   7.91044776  1.1029412     C
12    C   4.02985075  1.0441176     C
13    C   3.43283582  0.7500000     C
14    D  19.85892857  5.7023070     D
15    D  15.21785714  3.2076197     D
16    D   8.00357143  2.3692545     D
17    D   7.67142857  3.0929227     D
18    D   5.75357143  3.8173552     D
19    E  96.26288660  5.5576024     E
20    E 118.41752580  4.3844430     E
21    E  88.97938144  4.3557405     E
22    E  33.16752577  6.1140918     E
23    E   8.27164948  4.8505888     E
24    F  23.54920101  2.7593361     F
25    F  20.52144659  2.3236515     F
26    F  15.97981497  3.0497925     F
27    F  56.09756097  5.6639004     F
28    F  37.93103448  6.2448133     F
29    F   2.80908326  5.5186722     F
30    F   5.53406223 11.0373444     F
31    F   4.85281750  5.2282158     F
32    F   9.92430614  1.8879668     F
33    F   0.36809306  5.6639004     F
34    F   2.73338940  1.8879668     F
35    F   3.94449117  6.3900415     F
36    F   1.59798150  3.9211618     F
37    F   4.39865433  2.6141079     F
38    F   1.21951220 33.5477178     F
39    F  40.84051724  4.3388430     F
40    F  36.96120690  2.4586777     F
41    F  35.02155172  3.3264463     F
42    F  44.71982759  0.8677686     F
43    F  52.47844828  0.8677686     F
44    F   4.41379310  2.0247934     F
45    F   1.45358090  7.2314050     F
46    F   0.25615763 17.6446281     F
47    F   5.08222812  1.1570248     F
48    F   0.25615763 30.8057851     F
49    F   3.26790451  5.7851240     F
50    F   3.84084881  4.4834711     F
51    F   2.02652520  8.8223140     F
52    F   5.17771883  2.0247934     F
53    F   0.05941645 12.5826446     F
54   F1  68.20857863  2.7593361     F
55   F1  64.42388562  2.3236515     F
56   F1  72.91645498  3.3402490     F
57   F1  60.63919260  2.1784232     F
58   F1  59.12531539  3.1950207     F
59   F1  56.09756097  4.2116183     F
60   F1  51.55592935  3.7759336     F
61   F1  50.04205214  2.4688797     F
62   F1  49.28511354 11.0373444     F
63   F1  68.96551724  0.8677686     F
64   F1  76.79352531  0.5785124     F
65   F1  79.59555352  2.8925620     F
66   F1  55.38793103  0.8677686     F
67   F1  51.50862069  1.3016529     F
68   F1  53.44827586  5.9297521     F
69   F1  49.56896552  1.1570248     F
70   F1  43.75000000  0.7231405     F
71   F1  44.71982759  7.9545455     F
72    G  31.69856459  2.0000000     G
73    G  61.60287081  4.0000000     G
74    G  53.22966507  8.0000000     G
75    G   8.97129187 12.0000000     G
76    G  10.16746411  6.0000000     G
77    G   9.56937799  5.0000000     G
78    G   8.97129187  5.0000000     G

Any help would be appreciated

2 Answers

One approach is to pre-calculate the color you want to apply ahead of time with mutate and case_when. This saves us from having to manually define each color. TRUE ~ "white" just makes everything else white.

Then, crucially, you must insure the points you want to fill have a shape that is compatible with a fill, specifically shapes 21, 22, 23, 24, or 25. You can insure this by manually defining them with scale_shape_manual. Finally, use scale_fill_manual to define the colors.

If we want to set up the legend, we can define the labels in scale_shape_manual. Then we can call guides to override the shapes to ones that are compatible with fill.

mydata %>%
  mutate(fill.col = case_when(site == "F" ~ "black",
                              site == "F1" ~ "gray",
                              TRUE ~ "white")) %>%
ggplot(aes(y=density,x=Do, color=color, shape=color, group=site, fill = fill.col)) +
  geom_point(size=3.5)+stat_smooth(method="lm",se=FALSE) +
  scale_shape_manual(values = c(A = 3, B = 4, C = 21, D = 22, E = 23, F = 24, F1 = 25, G = 8)) +
  scale_fill_manual(values = c(black = "black",gray = "gray",white = "white"),
                    labels = c(black = "F", gray = "F1", white = "Other"))+
  scale_y_log10() + scale_x_log10()+
  labs(x = "Do", y = bquote('density'~(No.m^-3))) +
  theme_classic() +
  theme(aspect.ratio=1,
        axis.title.x = element_text(color = 'black',face = 'bold',size = 18, hjust = 0.5),
        axis.title.y = element_text(color = 'black',face = 'bold',size=25, hjust = 0.5),
        legend.title = element_text(size=8, color = "white"),
        legend.position=c(0.17, 0.20),
        legend.text = element_text(color = "black",face = 'bold', size=14)) +
  guides(fill = guide_legend(override.aes = list(shape = c(24,24,21),
                                                 linetype = NA)))

enter image description here

Here is a solution similar to Ian Campbell's. But it uses named vectors instead. Those vectors are created beforehand based on the unique site's and given appropriate values, note the shapes 23, chosen because that's a value that can be filled. Their names are the sites.

sites <- unique(mydata$site)
shapes <- setNames(c(0:4, 23, 23, 6), sites)
sites <- setNames(rep("white", length(sites)), sites)
sites[names(sites) == "F1"] <- "grey"

ggplot(mydata, aes(Do, density, color = color, shape = color))+
  geom_point(aes(fill = site), size = 3.5, show.legend = FALSE)+
  stat_smooth(method = "lm", formula = y ~ x, se = FALSE) +
  scale_fill_manual(values = sites) +
  scale_shape_manual(values = shapes) +
  scale_y_log10()+
  scale_x_log10()+
  labs(x = "Do", y = bquote('density'~(No.m^-3)))+
  theme_classic()+
  theme(
    aspect.ratio = 1,
    axis.text = element_text(family = "Sans"),
    axis.title = element_text(color = 'black', face = 'bold', hjust = 0.5),
    axis.title.x = element_text(size = 18),
    axis.title.y = element_text(size = 25),
    legend.title = element_text(size = 8, color = "white"),
    legend.position = c(0.17, 0.20),
    legend.text = element_text(color = "black", face = 'bold', size = 14)
  )

enter image description here

Related