Kate Jang
Kate Jang

Reputation: 21

ggplots2 combination of geom_line and geom_point creates too many shapes along lines

I am working on 3-way interaction effect plotting using my own data. But my code creates too many (continuous) shapes along the lines.

Attached please see my figure I got.

How can I leave the points only at the ends of the lines instead of the figure attached above?

I will deeply appreciate if anybody helps.

    g1=ggplot(mygrid,aes(x=control,y=pred,color=factor(nknowledge),
                 lty=factor(nknowledge),shape=factor(nknowledge)))+
    geom_line(size=1.5)+
    geom_point(size=2.5)+
    labs(x="control", y="attitudes",lty = "inc level")+
    scale_linetype_manual("know level",breaks=1:3,values=c("longdash", "dotted","solid"),label=c("M-SD","M","M+SD"))+
    scale_color_manual("know level",breaks=1:3,values=c("red", "blue","grey"),label=c("M-SD","M","M+SD"))+
    scale_shape_manual("know level",breaks=1:3,values=c(6,5,4),label=c("M-SD","M","M+SD"))+
    theme_classic()

Upvotes: 2

Views: 230

Answers (2)

Arthur Yip
Arthur Yip

Reputation: 6230

If you use geom_point, then you'll get points for all rows in your data frame. If you want specific points and shapes plotted at the ends of your lines, you'll want to create a filtered data frame for the only points you want to have plotted.

library(ggplot2); library(dplyr)
g1 <- ggplot()+
  geom_line(data = mtcars,
            mapping = aes(x=hp,y=mpg,color=factor(cyl),lty=factor(cyl)),
            size=1.5)+
  geom_point(data = mtcars %>% group_by(cyl) %>% filter(hp == max(hp) | hp == min(hp)),
             mapping = aes(x=hp,y=mpg,color=factor(cyl),shape=factor(cyl)),
             size=2.5)
g1

Created on 2021-01-28 by the reprex package (v0.3.0)

Upvotes: 1

stefan
stefan

Reputation: 125707

This could be achieved by making use of a second dataset which filters the data for the endpoints by group using e.g. a group_by and range and passing the filtered dataset as data to geom_point:

Using some random example data try this:

set.seed(42)

mygrid <- data.frame(
  control = runif(30, 1, 7),
  pred = runif(30, 1, 3),
  nknowledge = sample(1:3, 30, replace = TRUE)
)

library(ggplot2)
library(dplyr)

mygrid_pt <- mygrid %>% 
  group_by(nknowledge) %>% 
  filter(control %in% range(control))

ggplot(mygrid,aes(x=control,y=pred,color=factor(nknowledge),
                     lty=factor(nknowledge),shape=factor(nknowledge)))+
  geom_line(size=1.5)+
  geom_point(data = mygrid_pt, size=2.5)+
  labs(x="control", y="attitudes",lty = "inc level")+
  scale_linetype_manual("know level",breaks=1:3,values=c("longdash", "dotted","solid"),label=c("M-SD","M","M+SD"))+
  scale_color_manual("know level",breaks=1:3,values=c("red", "blue","grey"),label=c("M-SD","M","M+SD"))+
  scale_shape_manual("know level",breaks=1:3,values=c(6,5,4),label=c("M-SD","M","M+SD"))+
  theme_classic()

Upvotes: 2

Related Questions