Search code examples
rggplot2plotlylegendpie-chart

Arrange 4 plotly pie graphs in R


I have four separate pie graphs all with the same specified color scheme (the code is identical apart from the dataframe).

The colors are designated because I want to combine them in the 4 grid graph with one legend using the same designated colors for each of the 5 groups (ie. when the colors are not designated, the colors are automatically allocated based on the size of the group).

Example Data:

# Data
g = c("D","L","X","A","N","B")
v = c(49,14,9,7,6,5)

df1 = data.frame(group = g, value = v)
set.seed(9) # Just for reproductibility
df2 = data.frame(group = sample(g,size = nrow(df1),replace = F),
                 value = sample(v,size = nrow(df1),replace = F)
                 )

set.seed(8) 
df3 = data.frame(group = sample(g,size = nrow(df1),replace = F),
                 value = sample(v,size = nrow(df1),replace = F)
)

set.seed(7)
df4 = data.frame(group = sample(g,size = nrow(df1),replace = F),
                 value = sample(v,size = nrow(df1),replace = F)
)

piegraph data

The code:

BC <- 

       plot_ly(b_c, labels = ~group, values = ~value, marker = list(colors = c(  '#2ca02c',  '#d62728','#9467bd', '#FF7F0E', '#1F77B4')), type = 'pie',textposition = 'outside',textinfo = 'label+percent') %>%
       layout(title = 'b_c',autosize = F, width = 690, height = 690, margin = m,
              xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
              yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
     BC   

I have reviewed these posts, but have not been able to determine an answer for combing the plots from these.

Subplots deploying in R Plotly

Plotting multiple pie charts in plotly

I am looking for something similar to ggarrange in ggplot

I have four sets of data, some of which have the same groups (ie. the same row names). For these I would like to use the same color.

I don't really mind about the color scheme (ie. can be any color), but would like to have a unifying color legend for all 4 piegraphs.


Solution

  • Hi @sar give a look if it solves your problem:

    library(plotly)
    library(dplyr)
    
    # Data
    g = c("D","L","X","A","N","B")
    v = c(49,14,9,7,6,5)
    
    df1 = data.frame(group = g, value = v)
    set.seed(9) # Just for reproductibility
    df2 = data.frame(group = sample(g,size = nrow(df1),replace = F),
                     value = sample(v,size = nrow(df1),replace = F)
                     )
    
    set.seed(8) 
    df3 = data.frame(group = sample(g,size = nrow(df1),replace = F),
                     value = sample(v,size = nrow(df1),replace = F)
    )
    
    set.seed(7)
    df4 = data.frame(group = sample(g,size = nrow(df1),replace = F),
                     value = sample(v,size = nrow(df1),replace = F)
    )
    
    
    #Plot
    
    plot_ly(labels = ~group, values = ~value, legendgroup = ~group,
            textposition = 'outside',textinfo = 'label+percent') %>%
      add_pie(data = df1, name = "DF1", domain = list(row = 0, column = 0))%>%
      add_pie(data = df2, name = "DF2", domain = list(row = 0, column = 1))%>%
      add_pie(data = df3, name = "DF3", domain = list(row = 1, column = 0))%>%
      add_pie(data = df4, name = "DF4", domain = list(row = 1, column = 1))%>%
      layout(title = "Pie Charts in Grid", showlegend = T,
             grid=list(rows=2, columns=2),
             xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
    
    

    The Output:

    plot

    EDIT1: To show "subtitles" for each pie you can use annotations, you can also change the the legend position. The drawnback of annotations is that you must specify the position(mannualy in this case).

    For avoid overlaping I suggest remove textposition = 'outside'.

    You can download the plot as .png with the button on top right of the plot.

    #Plot
    
    plot_ly(labels = ~group, values = ~value, legendgroup = ~group, 
            textinfo = 'label+percent') %>%
      add_pie(data = df1, name = "DF1", domain = list(row = 0, column = 0))%>%
      add_pie(data = df2, name = "DF2", domain = list(row = 0, column = 1))%>%
      add_pie(data = df3, name = "DF3", domain = list(row = 1, column = 0))%>%
      add_pie(data = df4, name = "DF4", domain = list(row = 1, column = 1))%>%
      layout(title = "Pie Charts in Grid", showlegend = T,
             grid=list(rows=2, columns=2),
             xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             legend = list(y = 0.5),
             annotations = list(x = c(.08, .62, .08, .62),
                                y = c(.78, .78, .22, .22),
                                text = c("Pie 1","Pie 2","Pie 3","Pie 4"),
                                xref = "papper",
                                yref = "papper",
                                showarrow = F
                              )
             )
    

    The new output is: plot2

    EDIT2: Give a look in font or text font.

    You can change text and hover text as you please with a template.

    Here is an edit suggesting taking off the labels to get more space for percentage and rounding percentage to 1 decimal digit:

    #Plot
    
    plot_ly(labels = ~group, values = ~value, legendgroup = ~group, textinfo = 'label+percent',
            texttemplate = "%{percent:.1%}",
            hovertemplate = "%{label} <br> %{percent:.1%} <br> %{value}") %>%
      add_pie(data = df1, name = "DF1", domain = list(row = 0, column = 0))%>%
      add_pie(data = df2, name = "DF2", domain = list(row = 0, column = 1))%>%
      add_pie(data = df3, name = "DF3", domain = list(row = 1, column = 0))%>%
      add_pie(data = df4, name = "DF4", domain = list(row = 1, column = 1))%>%
      layout(title = "Pie Charts in Grid", showlegend = T,
             grid=list(rows=2, columns=2),
             xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
             legend = list(y = 0.5),
             annotations = list(x = c(.08, .62, .08, .62),
                                y = c(.78, .78, .22, .22),
                                text = c("Pie 1","Pie 2","Pie 3","Pie 4"),
                                xref = "papper",
                                yref = "papper",
                                showarrow = F
                              )
             )
    

    New Output:

    plot3