Home > Software engineering >  How to adjust the the y axis like this in ggplot2?
How to adjust the the y axis like this in ggplot2?

Time:06-12

Here is the codes and the present outplot

df <- data.frame(state = c('0','1'),
                                male = c(26287942,9134784),
                                female = c(16234000,4406645))
#output
> df
  state     male   female
1     0 26287942 16234000
2     1  9134784  4406645
library(ggplot2)
library(tidyr)

df_long <- pivot_longer(df, cols = c("female","male"))
names(df_long) <- c('state','sex','observations')
ggplot(data = df_long)  
  geom_col(aes(x = sex, y =observations, fill = state))   
   theme(legend.position = c(0.1,0.9),  
   legend.background = element_rect(fill='lightgrey') )

My present output

I want to adjust the plots like this. (I marked what I want to change.) Desired picture

  1. Simplify the scientific records in y-axis.
  2. Count the ratio (the number of state 1)/(the number of state 0 state 1) and plot like this.

It may be a little complicated, and I don't know which functions to use. If possible, can anyone tell me some related functions or examples?

CodePudding user response:

You can set options(scipen = 99) to disable scientific notation on y-axis. We can create a separate dataset for label data.

library(tidyverse)

options(scipen = 99)

long_data <- df %>% 
  pivot_longer(cols = c(male, female), 
               names_to = "sex", 
               values_to = "observations")

label_data <- long_data %>%
  group_by(sex) %>%
  summarise(perc = observations[match(1, state)]/sum(observations), 
            total = sum(observations), .groups = "drop")

ggplot(long_data)   
  geom_col(aes(x = sex, y = observations, fill = state))  
  geom_text(data = label_data, 
            aes(label = round(perc, 2), x = sex, y = total), 
            vjust = -0.5)   
  theme(legend.position = c(0.1,0.9),  
        legend.background = element_rect(fill='lightgrey'))

enter image description here

CodePudding user response:

By searching the Internet for about two days, I have finished the work!

sex <- c('M','F')
y0 <- c(26287942,16234000)
y1 <- c(9134784, 4406645)
y0 <- y0*10^{-7}
y1 <- y1*10^{-7}
ratio <- y1/(y0 y1)
ratio <- round(ratio,2)
m <- t(matrix(c(y0,y1),ncol=2))
colnames(m) <- c(as.character(sex))
df <- as.data.frame(m)
df <- cbind(c('0','1'),df)
colnames(df)[1] <- 'observations'
df
df_long <- pivot_longer(df, cols = as.character(sex))
names(df_long) <- c('state','sex','observations')
df_r <- as.data.frame(df_long)            
df_r <- data.frame(df_r,ratio=rep(ratio,2))
ggplot(data = df_r)  
  geom_col(aes(x =sex, y = observations, fill = state)) 
  theme(legend.position = c(0.1,0.9),
        legend.background = element_rect(fill=NULL) ) 
  geom_line(aes(x=sex,y=ratio*10),group=1) 
  geom_point(aes(x=sex,y=ratio*10)) 
  geom_text(aes(x=sex,y=ratio*10 0.35),label=rep(ratio,2)) 
  scale_y_continuous(name =expression(paste('observations(','\u00D7', 10^7,')')),
                     sec.axis = sec_axis(~./10,name='ratio'))

The output: Output

  • Related