Search code examples
rggplot2powerbiplotly

Multiple scale selection in same Y axis


I am trying to use a large dataset for visualization and my data is in long format. I would like to plot a variable Y1 on Y axis, and legend shall be different color based on another variable attribute.

Data looks like below:

enter image description here

Now, since Y1 values are quiet differing for each attribute, we can not clearly visualize the trends due to same scale. I do not want dual Y axix chart (primary and secondary axis).

I have searched here and some other links, but not successful in getting the right path.

plotting multiple feature on y axis with different y axis scaling

Target is to get multiple scale on same Y axis, as depicted here, closer to my expectations:

enter image description here

I am working in Power Bi and can create visual with R as well. Please suggest suitable tools/path.


Solution

  • Here are two approaches in R, one using ggplot2 and another with base graphics:

    First make a toy dataset with three attributes on different scales:

    df <- expand.grid(attribute=c("A","B","C"),x=1:1000)
    df$y = runif(3000) * 10^(df$attribute=="A") * 10^(df$attribute=="C")
    
    head(df)
    
      attribute x           y
    1         A 1   1.5744261
    2         B 1   0.1675056
    3         C 1 976.0232542
    4         A 2   4.1204111
    5         B 2   0.4594168
    6         C 2 449.7775410
    
    

    With ggplot use facet_grid, and use the strip labels as axis labels:

    library(ggplot2)
    
    ggplot(df) + 
      aes(x=x,y=y, col=attribute) + 
      geom_line() + 
      facet_grid(rows=vars(attribute),scale="free",switch = "y") + 
      theme(strip.placement = "outside", 
            strip.background = element_blank(),
            legend.position = "none") + 
      labs(y=NULL) 
    

    enter image description here

    In base R, find the unique values of attribute then loop through them, only plotting the axes you need for each graph. Use par to get the individual margins and the outer margin right:

    par(mfrow=c(3,1),mar=c(1,5,0,5),oma=c(6,0,6,0))
    a=unique(df$attribute)
    for(i in seq_along(a)){
      with(df[df$attribute==a[i],], plot(x,y,type="l",col=i,ylab=a[i],axes=FALSE))
      axis(side = 2,las=1)
    }
    axis(side = 1)
    
    

    enter image description here