LT17
LT17

Reputation: 353

Customised Bubble plot

I am trying to do a bubble plot. My data are:

Year<-rep(2001:2005, each = 5)
name<-c("John","Ellen","Mark","Randy","Luisa")
Name<-c(rep(name,5))
Value<-sample(seq(0,25,by=1),25)
mydata<-data.frame(Year,Name,Value)

And by far I've got to this point:

ggplot(mydata, aes(x=Year, y=Name, size = Value)) +
  geom_point() +
  theme(axis.line = element_blank(),
        axis.text.x=element_text(size=11,margin=margin(b=10),colour="black"),
        axis.text.y=element_text(size=13,margin=margin(l=10),colour="black",
                                 face="italic"),
        axis.ticks = element_blank(),
        axis.title=element_text(size=18,face="bold"),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        legend.text = element_text(size=14),
        legend.title = element_text(size=18))

I need many modifications but I couldn't understand how to do that (I am not very familiar with ggplot2). First, I would like to use the viridis scale, but neither scale_color_viridis nor scale_fill_viridis are working (I have also tried setting the discrete=T argument).

Second, I would like to avoid the 0 values to be plotted (i.e., having a blank space where the 0 value is being plotted), but neither using na.omit (e.g. as ggplot(na.omit(mydata), aes(x=Year, y=Name, size = Value)) or as ggplot(mydata, aes(x=Year, y=Name, size = na.omit(Value)))) or removing the 0 from Value object work.

Third, I'd like the legend to be a continuous scale: the plotted values of Value are in a range from 1 to 25 (as I would like to remove the zeros) but the default legend is discrete with 5 points break.

I would like the plot to look more or less like this (with the bubble sizes depending on the value of Value):

desired plot

Any suggestions? Sorry for the many questions but I have some real difficulties in understanding how ggplot works. Thanks!

Upvotes: 0

Views: 1230

Answers (3)

Dr. Fabian Habersack
Dr. Fabian Habersack

Reputation: 1141

Just as an alternative way to think about this... maybe it's helpful. :-)

library(tidyverse)

set.seed(123)

df <- tibble(
  year = rep(2001:2005, each = 5),
  name = rep(c("John","Ellen","Mark","Randy","Luisa"),5),
  value = sample(seq(0,25,by=1),25)
)

df %>%
  mutate(name_2 = ifelse(year>2001 & year<2005, NA, name)) %>%
  ggplot(aes(year, value, group = name, label = name_2, color = name)) + 
  geom_line() +
  geom_point() +
  geom_text(vjust = -1) +
  scale_color_brewer(palette = "Set1") +
  theme_minimal(base_family = "serif") +
  theme(legend.position = "none") +
  xlab("")

enter image description here

Upvotes: 0

teunbrand
teunbrand

Reputation: 38043

In order to map a variable in your data to some scale, you use the aes() function to couple what ggplot2 calls an 'aesthetic' to an expression (typically a symbol for a column in your data). Thus, to make a colour scale, you have to specify a colour aesthetic inside the aes() function. In the code below, I also specify an alpha aesthetic, which is 1 if Value > 0 and 0 otherwise, making the 0-value points completely transparent. I specify I() to let ggplot2 know that it should take this value literally instead of mapping it to a scale.

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.0.3

Year<-rep(2001:2005, each = 5)
name<-c("John","Ellen","Mark","Randy","Luisa")
Name<-c(rep(name,5))
Value<-sample(seq(0,25,by=1),25)
mydata<-data.frame(Year,Name,Value)

g <- ggplot(mydata, aes(x=Year, y=Name, size = Value)) +
  geom_point(aes(colour = Value, 
                 alpha = I(as.numeric(Value > 0))))

Once we have specified the aesthetics, we can begin customising the scales. The typical pattern is scale_{the aesthetic}_{type of scale}, so we need to add scale_colour_viridis_c() if we want to map the colour values to the viridis scale (the *_c is for continuous scales). In the scales, we can specify for example the limits, which you've indicated should be between 1 and 25. Also, I added a scale_size_area() where we say that we do not want a legend for the size of the points by setting `guide = "none".

g + scale_colour_viridis_c(option = "C", direction = -1,
                         limits = c(1, 25)) +
  scale_size_area(guide = "none") +
  theme(axis.line = element_blank(),
        axis.text.x=element_text(size=11,margin=margin(b=10),colour="black"),
        axis.text.y=element_text(size=13,margin=margin(l=10),colour="black",
                                 face="italic"),
        axis.ticks = element_blank(),
        axis.title=element_text(size=18,face="bold"),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        legend.text = element_text(size=14),
        legend.title = element_text(size=18))

Created on 2021-02-24 by the reprex package (v1.0.0)

Upvotes: 0

Max Teflon
Max Teflon

Reputation: 1800

Is that what you are looking for?

library(ggplot2)

Year<-rep(2001:2005, each = 5)
name<-c("John","Ellen","Mark","Randy","Luisa")
Name<-c(rep(name,5))
Value<-sample(seq(0,25,by=1),25)
Value <- ifelse(Value == 0, NA, Value)
mydata<-data.frame(Year,Name,Value)

ggplot(mydata, aes(x=Year, y=Name, size = Value, colour = Value)) +
  geom_point() +
  scale_colour_viridis_c() +
  scale_size(guide = F) +
  theme(axis.line = element_blank(),
        axis.text.x=element_text(size=11,margin=margin(b=10),colour="black"),
        axis.text.y=element_text(size=13,margin=margin(l=10),colour="black",
                                 face="italic"),
        axis.ticks = element_blank(),
        axis.title=element_text(size=18,face="bold"),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        legend.text = element_text(size=14),
        legend.title = element_text(size=18))
#> Warning: Removed 1 rows containing missing values (geom_point).

Concerning your points: I did only see the scale_colour_viridis_c and the scale_colour_viridis_b functions which differ in the colors as far as I could see. Maybe I am missing some package?

Secondly regarding the NAs: you just needed to replace the 0s by NAs.

And lastly regarding the scale: The color-scale is automatically continuous. Depicting sizes continuously is a bit tricky, therefore it will always be discrete. But I removed it from the legend for you so that you only have the color there as in your example.

Upvotes: 0

Related Questions