Unique color ramp using factor with positive value

2019-08-04 08:21发布

I'm trying to create a color ramp to plot in ggplot2 which is dependent on factors and numbers. I'll like the color ramp to be positive above and below. In my case I want to look at dominant gender population for each point.

##Create dataframe
DF1 <- data.frame(A=c("Female","Male","Male","Female","Male","Male"),
B=c(0.2,0.5,0.4,0.8,0.1,0.5), X <- c(1,2,3,4,5,6), Y <- c(1,4,3,2,3,1))
colnames(DF1)<-c("Sex", "Ratio", "X", "Y")

A sample plot of the data using ggplot just coloured it categorically not with a colour ramp.

##Basic plot using ggplot2
 ggplot()  + geom_point(data=DF1, aes(X,Y,colour=A),fill=B,alpha=0.8)

I'll like to create a colour ramp which is positive both sides of zero with one side is red and the other is blue based on "Sex". The colour intensity will be dependent on the "Ratio". What is the best way to do this please?

标签: r ggplot2 plot
2条回答
孤傲高冷的网名
2楼-- · 2019-08-04 08:29

I decided to stick with new labels with amendment to the answer by @divisan. So, the first step would be to do a trial plot to determine the number breaks and then plot properly.

  DF1 <- data.frame(A=c("Female","Male","Male","Female","Male","Male"),
              B=c(0.2,0.5,0.4,0.8,0.1,0.5), X <- c(1,2,3,4,5,6), Y <- c(1,4,3,2,3,1))
colnames(DF1)<-c("Sex", "Ratio", "X", "Y") 

#Edit table to ensure both genders are negative or positive
 DF2 <- DF1 %>% mutate(sex_ratio = (as.numeric(Sex) * 2 - 3) * Ratio)

#Plot to view data range and number breaks of color ramp
ggplot()  + geom_point(data=DF2, aes(X,Y,colour=sex_ratio),alpha=0.8) +
scale_color_gradient2(low = 'red', mid = 'white', high = 'blue',midpoint=0)    

enter image description here

#To plot fully
ggplot() + theme_bw  + geom_point(data=DF2, aes(X,Y,colour=sex_ratio ,size=Ratio),alpha=0.8) +
scale_color_gradient2(low = 'red', mid = 'white', high = 'blue',midpoint=0,
     labels = c("0.75","0.50","0.25","0","0.25","0.50"), name= "Gender") 

enter image description here

查看更多
对你真心纯属浪费
3楼-- · 2019-08-04 08:49

I see 2 ways to do this:

The Simple Way: Set color = Sex and then use alpha = Ratio to adjust color saturation.

ggplot(DF1) +
    geom_point(aes(X, Y, color = Sex, alpha = Ratio)) +
    scale_color_manual(values = c('Male' = 'blue', 'Female' = 'red'))

enter image description here

This approach is simple and doesn't require changing variables, but you get a:

Red -> Clear -> Blue gradient instead of a Red -> White -> Blue gradient


The Nicer Way: If you want to keep a clearer Red -> White -> Blue gradient, you should combine Sex and Ratio into a new variable that describes your desired colors before going into ggplot.

Sex is a factor, so we can convert it into a numeric and then change it into a -1:1 scale, rather than a 1:2 scale. Then we multiply it by Ratio to get a single numeric sex_ratio scale that incorporates both Sex and Ratio.

DF2 <- DF1 %>%
    mutate(sex_ratio = (as.numeric(Sex) * 2 - 3) * Ratio)

Now we can use scale_color_gradient2 to make your blue-white-red gradient scale:

ggplot(DF2) +
    geom_point(aes(X, Y, color = sex_ratio)) +
    scale_color_gradient2(low = 'red', mid = 'white', high = 'blue')

enter image description here


If you really want sex_ratio to be a positive range from 0 to 1, just tweak the values and set the midpoint of the gradient manually:

DF3 <- DF1 %>%
    mutate(sex_ratio = ((as.numeric(Sex) * 2 - 3) * Ratio + 1) / 2)

DF3$sex_ratio
[1] 0.40 0.75 0.70 0.10 0.55 0.75

ggplot(DF3) +
    geom_point(aes(X, Y, color = sex_ratio)) +
    scale_color_gradient2(low = 'red', mid = 'white', high = 'blue', midpoint = 0.5)

enter image description here

查看更多
登录 后发表回答