Here’s my attempt at creating a sales funnel using plotly (inspiration from this post). Feel free to provide feedback / improvements / suggestions: beaupre.steven@gmail.com
funnel
Label Step Number
1 main awareness 150000
2 ad landing awareness 80000
3 product 1 interest 80000
4 product 2 interest 40000
5 product 3 interest 35000
6 product 4 interest 25000
7 shopping cart desire 130000
8 thank you page action 120000
# Data prep
f <- funnel %>%
select(Step, Label, Number) %>%
mutate(Id = data.table::rleid(Step)) %>%
arrange(Id, desc(Label)) %>%
group_by(Step) %>%
mutate(Total = sum(Number),
RN = row_number(),
Cond = ifelse(n() > 1, 1, 0)) %>%
ungroup() %>%
mutate(Dummy = ifelse(RN == 1, (max(Total) - Total) / 2, 0)) %>%
group_by(Step) %>%
mutate(Max = Total + max(Dummy),
Pos = ifelse(Cond == 1,
cumsum(Number) - (0.5 * Number) + max(Dummy),
Max - (0.5 * Number)),
Low = max(Dummy)) %>%
ungroup() %>%
mutate(Rate = ifelse(Total / lag(Total) < 1,
paste0(" ", formatC(Total / lag(Total) * 100,
format = "f", digits = 2), "%"),
NA),
Text = ifelse(Cond == 1,
paste0(Label, "<br>", sprintf("%.0f", Number / 1000), "K"),
paste0(sprintf("%.0f", Number / 1000), "K")))
f
# A tibble: 8 x 13
Step Label Number Id Total RN Cond Dummy Max Pos Low Rate
<fctr> <fctr> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
1 awareness main 150000 1 230000 1 1 0 230000 75000 0 <NA>
2 awareness ad landing 80000 1 230000 2 1 0 230000 190000 0 <NA>
3 interest product 4 25000 2 180000 1 1 25000 205000 37500 25000 78.26%
4 interest product 3 35000 2 180000 2 1 0 205000 67500 25000 <NA>
5 interest product 2 40000 2 180000 3 1 0 205000 105000 25000 <NA>
6 interest product 1 80000 2 180000 4 1 0 205000 165000 25000 <NA>
7 desire shopping cart 130000 3 130000 1 0 50000 180000 115000 50000 72.22%
8 action thank you page 120000 4 120000 1 0 55000 175000 115000 55000 92.31%
# ... with 1 more variables: Text <chr>
# Annotations
anno <- list()
for (i in seq_len(nrow(f))) {
m <- f[i, ]
anno[[i]] <- list(
x = m$Pos,
y = m$Step,
text = m$Text,
showarrow = FALSE,
arrowhead = 0,
font = list(color = toRGB("white"), size = 10),
xanchor = "center")
}
str(anno[1])
List of 1
$ :List of 7
..$ x : num 75000
..$ y : Factor w/ 4 levels "action","awareness",..: 2
..$ text : chr "main<br>150K"
..$ showarrow: logi FALSE
..$ arrowhead: num 0
..$ font :List of 2
.. ..$ color: chr "rgba(255,255,255,1)"
.. ..$ size : num 10
..$ xanchor : chr "center"
# Plot
f %>%
plot_ly(x = Dummy, y = Step,
type = "bar",
orientation = "h",
marker = list(color = toRGB("white")),
showlegend = FALSE) %>%
add_trace(x = Number, y = Step,
type = "bar",
color = Label,
orientation = "h",
colors = c("#0D0887", "#3A049A", "#5E01A6", "#7E03A8",
"#9C179E", "#B52F8C", "#CB4679", "#DE5F65"),
showlegend = FALSE) %>%
add_trace(x = Low, y = Step,
mode = "lines",
line = list(width = 10,
color = toRGB("grey50"))) %>%
add_trace(x = 0, y = 0,
mode = "markers",
fill = 'tonextx',
fillcolor = "white",
marker = list(color = toRGB("white"))) %>%
add_trace(x = Max, y = Step,
mode = "text+lines",
line = list(width = 10,
color = toRGB("grey50")),
text = Rate,
textposition = "middle right",
textfont = list(size = 10,
color = toRGB("blue"))) %>%
add_trace(x = max(Max), y = 0,
mode = "markers",
fill = "tonextx",
fillcolor = toRGB("white"),
marker = list(color = toRGB("white"))) %>%
layout(yaxis = list(title = "",
autorange = "reversed",
tickmode = "array",
tickvals = Step),
xaxis = list(title = "",
zeroline = FALSE,
showticklabels = FALSE,
showgrid = FALSE),
barmode = "stack",
margin = list(l = 150),
annotations = anno,
showlegend = FALSE,
hovermode = FALSE,
bargap = 0.0000001)