0

In my example I created a second y-axis in ggplot. Instead of changing the colour for the data points of the second y-axis I want to change the shape. But, of course, I get the error Scale for 'shape' is already present. Adding another scale for 'shape', which will replace the existing scale. In the end I want to have a circle for "Large" and a filled circle for "Small" for "Visits" of the second y-axis.

This is my code:

Treatment <- c(rep(c("T/T"), times = 6),rep(c("R/R"), times = 6))
Size <- c(rep(c("Large", "Large", "Large", "Small", "Small", "Small"), times = 2))
Areatime <- c(240, 220, 120, 60, 55, 75, 90, 45, 70, 115, 40, 30)
Visits <- c(30, 45, 45, 65, 55, 55, 25, 35, 45, 75, 65, 55)
Counts <- data.frame(Treatment, Size, Areatime, Visits)

Counts$Treatment <- factor(Counts$Treatment, levels=c("T/T","R/R"))
Counts$inter <- interaction(Counts$Treatment, Counts$Size)
str(Counts)

ggplot(Count, aes(x = Treatment, y = Areatime)) +
  geom_jitter(aes(y = Areatime, shape = Size, width = 0.3)) +
  scale_shape_manual(values = c(0, 15), name = "Areatime", breaks = c("Large", "Small"),
    labels = c("Large", "Small")) +
  geom_jitter(aes(y = Counts*3, colour = Size, width = 0.3)) +
  scale_y_continuous(sec.axis = sec_axis(~./3, name = "Relative Visits [%]"))+
  scale_colour_manual(values =c(1, 2), name="Visits", breaks=c("Large", "Small"),
                     labels=c("Large", "Small")) +
  theme(axis.text.x=element_blank(),
                 panel.grid.major = element_blank(),
                 panel.grid.minor = element_blank(),
                 axis.ticks.x = element_blank(),
                 axis.line.x = element_blank(),
                 axis.line.y = element_line("black")) +
  facet_grid(.~Treatment, scales="free", switch = "x") +
  labs(y = "Average Areatime [sec]")

Plot of Example

MDC
  • 27
  • 4
  • 1
    Can you provide a reproducible example of your dataset ? (see: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – dc37 Feb 17 '20 at 20:57
  • I edited the original post and added a reproducible example. – MDC Feb 18 '20 at 13:30

2 Answers2

1

I played a bit around and it is not an elegant hack, but maybe it is good enough. You can use shape = 21 this is a fillable shape. Then you need to match the fill colour with the background color so it looks like it is not filled. There where some typo's in your example code. I hope I fixed them correctly.

Treatment <- c(rep(c("T/T"), times = 6),rep(c("R/R"), times = 6)) 
Size <- c(rep(c("Large", "Large", "Large", "Small", "Small", "Small"), times = 2)) 
Areatime <- c(240, 220, 120, 60, 55, 75, 90, 45, 70, 115, 40, 30) Visits <- c(30, 45, 45, 65, 55, 55, 25, 35, 45, 75, 65, 55) 

Counts <- data.frame(Treatment, Size, Areatime, Visits)

Counts$Treatment <- factor(Counts$Treatment, levels=c("T/T","R/R")) 
Counts$inter <- interaction(Counts$Treatment, Counts$Size) str(Counts)

ggplot(data = Counts, 
       aes(x = Treatment, 
           y = Areatime)) +   geom_jitter(aes(y = Areatime, 
                  colour = Size,
                  shape = Size),
              size = 3,
              width = 0.3) +   scale_shape_manual(values = c(0, 15),
                     name = "Areatime",
                     breaks = c("Large", "Small"),
                     labels = c("Large", "Small")) +   scale_colour_manual(values = c(1, 2)) +   geom_jitter(aes(y = Visits, 
                  fill = Size), 
              shape = 21, # this shape we can fill, but will give a border
              size = 3,
              width = 0.3) +   scale_y_continuous(sec.axis = sec_axis(~./3, name = "Relative Visits [%]"))+   scale_fill_manual(values = c("grey95", "red"),
                    name = "Visits",
                    breaks = c("Large", "Small"),
                    labels = c("Large", "Small")) +   guides(colour = guide_legend(title = "Areatime")) +   theme(axis.text.x=element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        axis.line.y = element_line("black")) +   facet_grid(. ~Treatment, 
             scales="free", 
             switch = "x") +   labs(y = "Average Areatime [sec]")

This while produce:

enter image description here

ricoderks
  • 1,619
  • 9
  • 13
0

Great, thanks! I just changed the colour for both to black instead of red and made the background the same gray colour and added the *3 in the second geom_jitter after "Visits" again (you just forgot because of my typo). So, the solution is:

ggplot(data = Counts, aes(x = Treatment, y = Areatime)) +
  geom_jitter(aes(y = Areatime, colour = Size, shape = Size), size = 3, width = 0.3) +
  scale_shape_manual(values = c(0, 15), name = "Areatime",
                     breaks = c("Large", "Small"), labels = c("Large", "Small")) +
  scale_colour_manual(values = c(1, 1)) +
  geom_jitter(aes(y = Visits*3, fill = Size), shape = 21, size = 3, width = 0.3) +
  scale_y_continuous(sec.axis = sec_axis(~./3, name = "Relative Visits [%]")) +
  scale_fill_manual(values = c("gray95", "black"),name = "Visits",
                    breaks = c("Large", "Small"), labels = c("Large", "Small")) +
  guides(colour = guide_legend(title = "Areatime")) +
  theme(axis.text.x=element_blank(),
                panel.background = element_rect(fill = "gray95"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                axis.ticks.x = element_blank(),
                axis.line.x = element_blank(),
                axis.line.y = element_line("black")) +
  facet_grid(. ~Treatment, scales="free", switch = "x") +
  labs(y = "Average Areatime [sec]")

Solution

MDC
  • 27
  • 4