I have created donut charts from plotly from the following:
library(plotly)
library(RColorBrewer)
test<-data_frame(Score=c("Green","Green","Yellow","Yellow","Clear","Clear","Red","Red"),Lang=c(rep("Eng",4),rep("Esp",4)))
test1<-data_frame(Score=c("Green","Yellow","Yellow","Yellow","Clear","Clear","Red","Red"),Lang=c(rep("Eng",4),rep("Esp",4)))
color_order<-c("Green","Clear","Yellow","Red")
colors<-c("#31a354","#bdbdbd","#fec44f","#de2d26")
a<-test %>%
mutate(Score=factor(Score,levels=color_order))%>%
arrange(Score)%>%
group_by(Score)%>%
summarize(count = n()) %>%
plot_ly(labels = ~Score,
values = ~count,
hoverinfo="skip",
text = ~count,
marker = list(colors = colors),
legendgroup = ~Score) %>%
add_pie(hole = 0.6) %>%
layout(title = "test chart1", showlegend = TRUE,
font=list(family="sans serif",color="#000"),
plot_bgcolor="#f0f0f0",
legend = list(orientation = 'h',font=list(size=28)),
xaxis = list(title=paste0("Total: ",nrow(test)), showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
b<-test1 %>%
mutate(Score=factor(Score,levels=color_order))%>%
arrange(Score)%>%
group_by(Score)%>%
summarize(count = n()) %>%
plot_ly(labels = ~Score,
values = ~count,
hoverinfo="skip",
text = ~count,
marker = list(colors = colors),
legendgroup = ~Score) %>%
add_pie(hole = 0.6) %>%
layout(title = "test chart2", showlegend = FALSE,
font=list(family="sans serif",color="#000"),
plot_bgcolor="#f0f0f0",
legend = list(orientation = 'h',font=list(size=28)),
xaxis = list(title=paste0("Total: ",nrow(test1)),showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
I am attempting to put them side by side with the common legend from plot a, and I run the following:
subplot(a,b,nrows = 1)
However, I only see one plot which appears to be a combination of the two. I also tried the approach here: Plotly: Bar and pie charts side by side, but it just gave me inception style donut within a donut. How can I put them next to each other with the common legend? Thanks.
According to this (https://plot.ly/r/pie-charts/), in order to create pie chart subplots, you need to use the domain attribute. You could try something like this (adjust domain for your needs):
a <- test %>%
mutate(Score=factor(Score,levels=color_order))%>%
arrange(Score)%>%
group_by(Score)%>%
summarize(count = n())
b<-test1 %>%
mutate(Score=factor(Score,levels=color_order))%>%
arrange(Score)%>%
group_by(Score)%>%
summarize(count = n())
p <- plot_ly() %>%
add_pie(data = a, labels = ~Score, values = ~count, hole = 0.6,
name = "a", domain = list(x = c(0, 0.4), y = c(0.4, 1))) %>%
add_pie(data = b, labels = ~Score, values = ~count, hole = 0.6,
name = "b", domain = list(x = c(0.6, 1), y = c(0.4, 1))) %>%
layout(title = "test chart1", showlegend = TRUE,
font=list(family="sans serif",color="#000"),
plot_bgcolor="#f0f0f0",
legend = list(orientation = 'h',font=list(size=28)),
xaxis = list(title=paste0("Total: ",nrow(test)), showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
Related
I've created a Plotly bar and pie chart and want to combine them to form one chart.
When I use subplot() to combine these Plotly charts, the pie & bar charts overlap.
Any advice on how to present these plots so that each is in its own row? Thank you.
Here's a picture of what I'm currently experiencing:
Reprex below:
#Pie chart example
pie_tibble <- tibble(donuts = c(49050, 66924),
group = c("Group A", "Group B"))
pie <- plot_ly(data = pie_tibble, labels = ~group, values = ~donuts, type = 'pie',
showlegend = F,
hoverinfo = "none",
marker = ~list(colors = c('#404040', '#24608B'))) %>%
layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
bar_tibble <- tibble(category = c("Cat 1", "Cat 1", "Cat 2", "Cat 2"),
pct_increase = c(0.17, 0.25, 0.64, 0.85),
week = c(1, 2, 1, 2))
#Bar chart example
bar <- plot_ly(data = bar_tibble, hoverinfo = "none") %>%
layout(
barmode = 'stack',
showlegend = F) %>%
add_trace(
x = ~pct_increase,
y = ~category,
type = "bar",
transforms = list(
list(
type = "aggregate",
groups = ~category,
aggregations = list(
list(
target = "x", func = "avg", enabled = T)))))
#Combine charts
subplot(bar, pie, nrows = 2)
Pie charts and plotly::subplot() are notoriously challenging - though you can get around many of the issues by specifying the domain manually. Below I have changed the pie code by specifying the domain = list(...) as so:
pie <- plot_ly(data = pie_tibble, labels = ~group, values = ~donuts, type = 'pie',
# Specify the domain here
domain = list(x = c(0.5, 0.5), # centered on x axis
y = c(0.0, 0.4)),
showlegend = F,
hoverinfo = "none",
marker = ~list(colors = c('#404040', '#24608B'))) %>%
layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
subplot(bar, pie, nrows = 2) now gives:
Sorry I don't have a more elegant answer, but hoping someone else might!
I have used bargap to decrease the width of bars in plotly but I want to bring themcloser whild keeping this width and not make them thicker.
library(tidyr)
library(stringr)
library(forcats)
library(plotly)
# data
Category<-c("First dose","Full vaccination")
`Uptake first dose`<-c(19.8,0)
`Uptake full vaccination`<-c(0,7.6)
`Not vaccinated`<-c(80.2,92.4)
ch5<-data.frame(Category,`Uptake first dose`,`Uptake full vaccination`,`Not vaccinated`)
# transform data
data.long <- ch5 %>%
pivot_longer(cols = -Category,
names_to = "vac",
values_to = "percent") %>%
mutate(vac = str_replace_all(vac, "\\.", " "),
vac = fct_rev(factor(vac)))
library(plotly)
plot_ly(data.long) %>%
add_bars(y = ~Category,
x = ~percent,
color = ~vac,
text = ~vac,
colors = c("#458d35", "#63bb47", "#e6e7e8"),
hovertemplate = paste('<b>%{y}</b>',
'<br>%{text}: %{x} ',
'<extra></extra>')) %>%
layout(font = list(color = '#a2a2a2'),barmode = "stack",
bargap = 0.7,
yaxis = list(fixedrange = TRUE,autorange="reversed",
title = "",
showticklabels = FALSE,
showgrid = FALSE,
showline = FALSE,
zeroline = FALSE),
xaxis = list(fixedrange = TRUE,title = "",ticksuffix = '%',
zeroline = FALSE,
showgrid = FALSE),
hoverlabel = list(bgcolor = "black",
bordercolor = "black",
font = list(color = "white")),
shapes = list(type = "line",
y0 = 0, y1 = 1, yref = "paper",
x0 = 70, x1 = 70),
annotations = list(text = "Target (70%)",
showarrow = FALSE,
x = 70,
y = 1.05,
yref = "paper"),
legend = list(orientation = 'h'))
I'm new to plotly, trying to figure out how to get a piechart to be aligned at the center of the entire plot area.
library(dplyr)
library(plotly)
data_for_plot <-
mtcars %>%
count(cyl)
> data_for_plot
## cyl n
## 1 4 11
## 2 6 7
## 3 8 14
plot_ly(data_for_plot, labels = ~cyl, values = ~n, type = 'pie', hole = 0.05 ,textposition = 'outside',textinfo = 'percent') %>%
layout(title = list(text = "my nice title is here", xanchor = "center"),
showlegend = F,
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE)) %>%
layout(paper_bgcolor = "pink")
So I get this pie chart, which is not centered:
I assume that inside layout() I need something that refers to the piechart itself, to assign it with xanchor = "center". But I researched this and couldn't find an answer.
Update on my attempts - 2020-01-18
I've tested the majority of attributes in layout() and still couldn't find something that would work with xanchor = "center". I've alse examined plotly's reference guide but so far to no avail.
Seems that the solution involves setting up the margin attribute within layout(). The solution is based on this hint, referring to this post. Implementing this to R is done using the following code:
plot_ly(data_for_plot, labels = ~cyl, values = ~n, type = 'pie', hole = 0.05 ,textposition = 'outside',textinfo = 'percent') %>%
layout(title = list(text = "my nice title is here", xanchor = "center"),
showlegend = F,
margin = list(l = 20, r = 20),
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = TRUE)) %>%
layout(paper_bgcolor = "pink")
I'm having a dataframe as follows
avgHours <- data.frame("QuarterYear" = c('2019 Q4','2020 Q1','2020 Q2'), average = c(44.5,44.5,42.0), leave = c(24.0,9.3,0.0), freeTime = c(0,0,0))
I need to plot 3 line graphs. In this case, I'm having a non-zero columns and 1 column with all the rows as 0. I need to omit that column while plotting.
This is the code for plotting the graph
plot_ly(avgHours) %>%
add_trace(x = avgHours$QuarterYear,
y = avgHours$average,
type = 'scatter',
mode = 'lines+markers+text',
hovertext = paste('Quarter: ', avgHours$QuarterYear,
'<br>Average hours per week: ', avgHours$average),
line = list(color = 'rgb(242,142,43)',
width = 3),
marker = list(color = 'rgb(242,142,43)',
size = 8),
hoverinfo = "text",
text = avgHours$average,
textposition = "top center",
name = "Average Hours")%>%
add_trace(x = avgHours$QuarterYear,
y = avgHours$leave,
type = 'scatter',
mode = 'lines+markers+text',
hovertext = paste('Quarter: ', avgHours$QuarterYear,
'<br>Average OOO hours per week: ', avgHours$leave),
line = list(color = 'rgb(205, 12, 24)',
width = 3),
marker = list(color = 'rgb(205, 12, 24)',
size = 8),
hoverinfo = "text",
text = avgHours$leave,
textposition = "top center",
name = "Leave Average Hours")%>%
add_trace(x = avgHours$QuarterYear,
y = avgHours$freeTime,
type = 'scatter',
mode = 'lines+markers+text',
hovertext = paste('Quarter: ', avgHours$QuarterYear,
'<br>Average Free Time per week: ', avgHours$freeTime),
line = list(color = '#003049',
width = 3),
marker = list(color = '#003049',
size = 8),
hoverinfo = "text",
text = avgHours$freeTime,
textposition = "top center",
name = "Free Time Average Hours")%>%
layout(
yaxis = list(
range = c(0,70),
title = "Average Hours Per Week"
)
) %>%
layout(hoverlabel = list(bgcolor= 'white'), showlegend = TRUE) %>%
layout(yaxis = list(showgrid = FALSE, zeroline = FALSE, showline = FALSE)) %>%
layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showline = FALSE)) %>%
layout(legend = list(orientation = "h",
xanchor = "center",
x = 0.5,
y = -0.13))
}
How can I plot the non-zero columns dynamically using plot_ly() in R?
Thanks in advance!!
You can have the add_trace in loop and specify the column selection by if condition as below:
p <- plot_ly(data = avgHours)
for(i in colnames(avgHours[-1])){
if(sum(avgHours[[i]])>0){
p <- p %>%
add_trace(x = avgHours[[1]],
y = avgHours[[i]],
type = 'scatter',
mode = 'lines+markers+text',
hovertext = paste('Quarter: ', avgHours[[1]],
'<br>Average hours per week: ', avgHours[[i]]),
line = list(width = 3),
marker = list(size = 8),
hoverinfo = "text",
text = avgHours[[i]],
textposition = "top center",
name = i)
}
}
p <- p %>%
layout(yaxis = list(
range = c(0,70),
title = "Average Hours Per Week")) %>%
layout(hoverlabel = list(bgcolor= 'white'), showlegend = TRUE) %>%
layout(yaxis = list(showgrid = FALSE, zeroline = FALSE, showline = FALSE)) %>%
layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showline = FALSE)) %>%
layout(legend = list(orientation = "h", xanchor = "center", x = 0.5, y = -0.13))
If you want to have specific colours for each line and markers, you can add the list of colours and sub-setting it.
Do we have something similar to our ggplot where
we define the color panel for each variable ?
scale_manual <- function(...){
ggplot2::manual_scale(
"fill",
values = setnames(c("green","red","blue","yellow","grey"),
c("var1","var2","var3","var4","var5")),
...
)
}
Although this Q seems to answer,
How can I change the colors of the slices in pie charts in plotly for r using hexadecimal strings?
but it is not working here.
Please consider an reprex below:
library(plotly)
USPersonalExpenditure <- data.frame("Categorie"=rownames(USPersonalExpenditure), USPersonalExpenditure)
data <- USPersonalExpenditure[,c('Categorie', 'X1960')]
p <- plot_ly(data, labels = ~Categorie, values = ~X1960, type = 'pie') %>%
layout(title = 'United States Personal Expenditures by Categories in 1960',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
#trial 1
plot_ly(data, labels = ~Categorie, values = ~X1960, type = 'pie', marker = list(color = rainbow(5))) %>%
layout(title = 'United States Personal Expenditures by Categories in 1960',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
# trial 2
plot_ly(data, labels = ~Categorie, values = ~X1960, type = 'pie', marker = list(color = brewer_pal(5, "Set3"))) %>%
layout(title = 'United States Personal Expenditures by Categories in 1960',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
Since there are many plots using the same data,
color need to be consistent.
So, trying to hard code for each variable.
I usually use Color mapping functions from the leaflet package before making interactive plots for shiny apps and plotly charts:
Hard code the color variable using your desired palette.
data$color <- leaflet::colorFactor(
palette = "Dark2", domain = data$Categorie
)(data$Categorie)
plot_ly(
data, labels = ~Categorie, values = ~X1960, type = 'pie',
marker = list( colors = ~color)
) %>%
layout(
title = 'United States Personal Expenditures by Categories in 1960',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE)
)
You may also hardcode it manually:
colors_list <- list(
"Food and Tobacco" = "#1B9E77",
"Household Operation" = "#D95F02",
"Medical and Health" = "#7570B3",
"Personal Care" = "#E7298A",
"Private Education" = "#66A61E"
)
data$color <- dplyr::recode(data$Categorie, !!!colors_list)
plot_ly(
data, labels = ~Categorie, values = ~X1960, type = 'pie',
marker = list( colors = ~color)
) %>%
layout(
title = 'United States Personal Expenditures by Categories in 1960',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE)
)