Search code examples
rlegendcontoursubplotr-plotly

Plot_ly contour plot in R common legend range colors not showing up correctly


I have created this contour plot with 5 subplots and common legend. As can be in the figure here, the min and max colors of the legend are based only on first subplot and not correct across all 5 plots. enter image description here

Is there a way to fix this? I am guessing it is small fix somewhere. Below the code I am using:

library(plotly)

VSL <- c(79000, 161000, 327000)
SCC <- c(35, 50, 100)

#Baseline
fig1 <- plot_ly(x=~VSL,y=~SCC,
  z = matrix(c(8.8,11.5,20.4,11.4,14.1,23.0,16.8,19.5,28.4), nrow = 3, ncol = 3), 
  type = "contour",coloraxis = 'coloraxis', contours = list(showlabels = TRUE,labelfont = list(size = 20, color = 'black')))

#EV Currentgrid
fig2 <- plot_ly(x=~VSL,y=~SCC, 
        z = matrix(c(8.2,10.6,18.6,11.0,13.4,21.3,16.7,19.1,27.0), nrow = 3, ncol = 3), 
        type = "contour",coloraxis = 'coloraxis', contours = list(showlabels = TRUE,labelfont = list(size = 20, color = 'black')))

#,contours = list(start = 6,end = 32,size = 2)

#EV Coal
fig3 <- plot_ly(x=~VSL,y=~SCC, 
                z = matrix(c(9.6,12.3,21.5,12.9,15.6,24.8,19.6,22.3,31.5), nrow = 3, ncol = 3), 
                type = "contour",coloraxis = 'coloraxis', contours = list(showlabels = TRUE,labelfont = list(size = 20, color = 'black')))

#EV NG
fig4 <- plot_ly(x=~VSL,y=~SCC, 
                z = matrix(c(7.4,9.7,17.1,9.6,11.9,19.4,14.2,16.4,23.9), nrow = 3, ncol = 3), 
                type = "contour",coloraxis = 'coloraxis', contours = list(showlabels = TRUE,labelfont = list(size = 20, color = 'black')))

#EV WWS
fig5 <- plot_ly(x=~VSL,y=~SCC, 
                z = matrix(c(6.4,8.3,14.5,8.5,10.4,16.6,12.8,14.6,20.9), nrow = 3, ncol = 3), 
                type = "contour",coloraxis = 'coloraxis', contours = list(showlabels = TRUE,labelfont = list(size = 20, color = 'black')))


fig <- subplot(fig1,fig2,fig3,fig4,fig5, shareY = TRUE)

annotations = list( 
  list(
    x = 0.08,  
    y = 1,
    text = "Baseline",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),  
  list(
    x = 0.3,  
    y = 1,  
    text = "EV Current grid",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),  
  list(
    x = 0.5,  
    y = 1,
    text = "EV Coal",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),
  list(
    x = 0.7,  
    y = 1,
    text = "EV NG",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),
  list(
    x = 0.9, 
    y = 1,
    text = "EV WWS",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),
  list(
    x = 1.05, 
    y = 1,
    text = "Total damages",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),
  list(
    x = 1.05, 
    y = 0.97,
    text = "(billion$)",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE 
  ),
  list(
    x = 0.5, 
    y = -0.157,
    text = "VSL",  
    xref = "paper",  
    yref = "paper",  
    xanchor = "center",  
    yanchor = "bottom",  
    showarrow = FALSE
    ))

fig <- fig %>% layout(coloraxis=list(colorscale='RdBu'),annotations = annotations)
fig

Solution

  • You need to manually define a start end end value for the contour range. There is a lot of awkward code duplication in your example, so I've created a shorter & tidier example.

    # This is your z-data; I recommend storing this as a `list` 
    # so you can loop over it using `lapply` or `purrr::map`.
    z_data <- list(
        fig1 = matrix(
            c(8.8,11.5,20.4,11.4,14.1,23.0,16.8,19.5,28.4), 
            nrow = 3, ncol = 3),
        fig2 = matrix(
            0.1 * c(8.2,10.6,18.6,11.0,13.4,21.3,16.7,19.1,27.0), 
            nrow = 3, ncol = 3))
    
    # Define the contour properties; `start`/`end` define the min/max
    # values of the shown contour range
    contours <- list(
        showlabels = TRUE,
        start = floor(min(unlist(z_data))),
        end = ceiling(max(unlist(z_data))),
        labelfont = list(size = 20, color = "black"))
    
    # Create a `list` of `plot_ly` objects
    lst <- lapply(z_data, function(z) 
        plot_ly(
            x = ~VSL,y = ~SCC, z = z,
            type = "contour",coloraxis = "coloraxis", contours = contours))
    
    # `subplot` accepts a `list` of `plot_ly` objects 
    subplot(lst, shareY = TRUE)
    

    enter image description here