I am trying to make a plot with mulitple groups, each group fit to a linear model one type I fit to an equally weighted model, the next time I fit to a model that is weighted by the number of points in the bin.
Here is some sample simulated data:
test_data <-
bind_rows(
tibble(test_x=rbeta(500,0.05,0.05),
test_y=5*test_x+4+runif(length(test_x),0,3),
group="group-a" ),
tibble(test_x=rbeta(500,0.05,0.05),
test_y=3*test_x+3+runif(length(test_x),0,3),
group="group-b" ),
) |>
mutate(test_x=floor(test_x * 20)/20 + 1/(2*20) ) |>
group_by(test_x,group) |> summarise(n=n(),test_y=mean(test_y))
and here is how a plot the data
test_data |> ggplot(aes(x=test_x,y=test_y,group=group,color=group)) +
geom_point() +geom_smooth(method = lm,se=FALSE) +
geom_smooth(aes(weight=n),method = lm,se=FALSE)
I can add linetype="dashed"
but that does not add to the legend. Can I add this to the legend?
Better yet, can I set the color/style for each line and customize the legend to have group-a weighted fit, group-a unweighted fit,group-b weighted fit, group-b unweighted fit?
forgot:
sessionInfo()
R version 4.3.3 (2024-02-29)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS 15.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: America/New_York
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] dplyr_1.1.4 ggplot2_3.5.1 tibble_3.2.1 devtools_2.4.5 usethis_3.1.0
loaded via a namespace (and not attached):
[1] generics_0.1.3 lattice_0.22-6 digest_0.6.37 magrittr_2.0.3 grid_4.3.3
[6] pkgload_1.4.0 fastmap_1.2.0 Matrix_1.6-5 pkgbuild_1.4.5 sessioninfo_1.2.2
[11] urlchecker_1.0.1 promises_1.3.2 mgcv_1.9-1 purrr_1.0.2 socR_0.5.9
[16] scales_1.3.0 cli_3.6.3 shiny_1.9.1 rlang_1.1.4 ellipsis_0.3.2
[21] munsell_0.5.1 splines_4.3.3 remotes_2.5.0 withr_3.0.2 cachem_1.1.0
[26] tools_4.3.3 memoise_2.0.1 colorspace_2.1-1 httpuv_1.6.15 vctrs_0.6.5
[31] R6_2.5.1 mime_0.12 lifecycle_1.0.4 fs_1.6.5 htmlwidgets_1.6.4
[36] miniUI_0.1.1.1 pkgconfig_2.0.3 pillar_1.10.0 later_1.4.1 gtable_0.3.5
[41] glue_1.8.0 profvis_0.4.0 Rcpp_1.0.13-1 tidyselect_1.2.1 rstudioapi_0.17.1
[46] farver_2.1.2 xtable_1.8-4 htmltools_0.5.8.1 nlme_3.1-166 labeling_0.4.3
[51] compiler_4.3.3
If you want to have a legend you have to map on aesthetics, i.e. move linetype=
inside aes()
.
Moreover, to achieve your preferred result, i.e. one legend with a separate entry for the groups aka color
and the type of model aka linetype
requires to use the interaction of both variables and to set the desired colors and linetypes using scale_xxx_manual
:
library(ggplot2)
test_data |> ggplot(aes(
x = test_x, y = test_y, group = group
)) +
geom_point() +
geom_smooth(
aes(
color = paste(group, "unweighted fit"),
linetype = paste(group, "unweighted fit")
),
method = lm, se = FALSE
) +
geom_smooth(
aes(
weight = n,
color = paste(group, "weighted fit"),
linetype = paste(group, "weighted fit")
),
method = lm, se = FALSE
) +
scale_color_manual(
values = rep(scales::hue_pal()(2), each = 2),
name = NULL
) +
scale_linetype_manual(
values = rep(c("solid", "dashed"), 2),
name = NULL
)