3
votes

For interactive 3D plots embedded in R shiny outputs, the R package plotly now offers some good options, especially as the maintenance of the alternative shiny-rgl package seems to be fading recently.

However, is it possible to create a 3d barplot using plotly?

1
Answering your own question is fine, but I don't quite understand what problem you are solving here. The answer could be improved by adding some explanation to what the "trick" is and how it works, as well as an image of the result. - Axeman
Modified to make the point clear. Run the below answer code in R to display the interactive 3d plot. - martin

1 Answers

2
votes

One trick to create the appearance of a 3d barplot is to plot error bars instead.

As commented in the below code, values of the dimension for which bars are desired are halved before supplying them via add_trace, where they are resized to anything below visibility (or making them transparent). The symmetric error bars of the halved values then simply lead to bars. Two groups of data df1 and df2 are added in the below example.

library(shiny)
library(plotly)

ui <- fluidPage(
    plotlyOutput("plotlii", width = "100%", height = "700px")
)

server <- function(input, output) {
    output$plotlii <- renderPlotly({
        # the data:     
        obs1 <- matrix(ncol=3,
            c(1,2,3,1,2,2,6,6,4)
        )
        df1 <- setNames(data.frame(obs1), c("a", "b", "c"))
        df1$c<-(.5*df1$c) # half values to make them the centre point of the bars
        obs2 <- matrix(ncol=3,
            c(14,16,10,11,12,12,23,23,22)
        )
        df2 <- setNames(data.frame(obs2), c("a", "b", "c"))
        df2$c<-(.5*df2$c) # half values to make them the centre point of the bars
        # the plot:
        p <- plot_ly(type="scatter3d",mode="markers",showlegend=FALSE)%>%
        add_trace(p,
            x = ~a, y = ~b, z = ~c,
            data = df1,
            color=I("red"),
            size = I(1),
            name = "Group a",
            error_z=list(
                color="red",
                thickness=0,
                symmetric = TRUE, 
                type = "data" ,
                array = df1$c
            )
        )%>%
        add_trace(p,
            x = ~a, y = ~b, z = ~c,
            data = df2,
            color=I("gray"),
            size = I(1),
            name = "Group a",
            error_z=list(
                color="gray",
                symmetric = TRUE, 
                type = "data" ,
                array = df2$c
            )
        )   
    })
}

shinyApp(ui, server)

enter image description here