How do I allow Plotly bar text to overflow past bar? - r

How do I get the text size for dr5 and dr3 for the shorter bars? If the text is longer than the bar span, I would like the text to overflow past the end of the bar.
I tried using uniformtext in layout, but that shrunk all text to the smallest font being used. How do I change all font to the biggest size being used?
library(plotly)
# Test long text and short bars
xValues <- c("loooooooooooooooooonnnnnngg","lonnnnnnnnnnggggggg",
"dr3","dr4","dr5")
yValues <- c(0.5,1,2,0.22,10)
bar <- plot_ly(x = yValues,
y = xValues) %>%
add_trace(
type = 'bar',
orientation = 'h',
text = xValues,
textangle = 360,
textposition = "inside",
insidetextanchor = "start",
showlegend = F) %>%
layout(
yaxis = list(zeroline = FALSE,showline = FALSE,showticklabels = FALSE),
uniformtext = list(mode = "show")
)
bar

This can be achieved by adding the labels via add_text like so:
BTW: I put the vectors inside a df. Seems more natural to me.
library(plotly)
# Test long text and short bars
xValues <- c("loooooooooooooooooonnnnnngg","lonnnnnnnnnnggggggg",
"dr3","dr4","dr5")
yValues <- c(0.5,1,2,0.22,10)
df <- data.frame(
x = xValues,
y = yValues
)
bar <- plot_ly(df, x = ~y, y = ~x, text = ~x) %>%
add_trace(
type = 'bar',
orientation = 'h',
showlegend = F) %>%
add_text(x = 0.1, textposition = "middleright") %>%
layout(yaxis = list(zeroline = FALSE,showline = FALSE, showticklabels = FALSE))
bar

Related

Create a stacked bar chart with 3 traces for 2 bars

I am trying to replicate the following stacked bar chart with plotly. I attach one screenshot for every hover text I get when hovering on a bar. As you will see there are 2 issues. First I cannot achieve 3 colors, besides the fact that I create them in the legend and secondly I cannot put First dose as top bar besides the fact that I use factor() based on the levels. Maybe there is an issue with the way I have created my dataset. I have no problem if you have to reform it instead of fix the plotly code to replicate the chart.
library(plotly)
Category<-c("First dose","Full vaccination")
`Uptake first dose`<-c(19.8,7.6)
`Uptake full vaccination`<-c(0,0)
`Not vaccinated`<-c(80.2,92.4)
ch5<-data.frame(Category,`Uptake first dose`,`Uptake full vaccination`,`Not vaccinated`)
ch5$Category <- factor(ch5$Category, levels = ch5[["Category"]])
ax <- list(
title = "",
showticklabels = FALSE,
showgrid = FALSE
)
fig <- plot_ly(ch5, y = ~Category, x = ~`Uptake first dose`,
type = 'bar', name = 'Uptake first dose',marker = list(color = 'lightgreen'))
fig <- fig %>% add_trace(x = ~`Uptake full vaccination`, name = 'Uptake full vaccination',marker = list(color = 'green'))
fig <- fig %>% add_trace(x = ~`Not vaccinated`, name = 'Not vaccinated',marker = list(color = 'gray'))
fig <- fig %>% layout(yaxis = ax,xaxis=list(title="",showgrid=F), barmode = 'stack')
fig
There might be a problem with your dataset. The 7.6% of full vaccination is listed under first doese. Therefore your coloring might not work.
Furthermore I transformed the data into a long format for an easy way to create hovertemplates.
library(plotly)
library(tidyverse)
# 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)))
# add plot
plot_ly(data.long) %>%
add_bars(y = ~Category,
x = ~percent,
color = ~vac,
text = ~vac,
colors = c("darkgreen", "green", "gray"),
hovertemplate = paste('<b>%{y}</b>',
'<br>%{text}: %{x} ',
'<extra></extra>')) %>%
layout(barmode = "stack",
yaxis = list(autorange="reversed"),
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.0%)",
showarrow = FALSE,
x = 70,
y = 1.05,
yref = "paper"))

How to apply subplot to a list of plots with secondary y axis

I want to prepare a subplot where each facet is a separate dual y-axis plot of one variable against the others. So I make a base plot p and add secondary y-axis variable in a loop:
library(rlang)
library(plotly)
library(tibble)
dual_axis_lines <- function(data, x, y_left, ..., facets = FALSE, axes = NULL){
x <- rlang::enquo(x)
y_left <- rlang::enquo(y_left)
y_right <- rlang::enquos(...)
y_left_axparms <- list(
title = FALSE,
tickfont = list(color = "#1f77b4"),
side = "left")
y_right_axparms <- list(
title = FALSE,
overlaying = "y",
side = "right",
zeroline = FALSE)
p <- plotly::plot_ly(data , x = x) %>%
plotly::add_trace(y = y_left, name = quo_name(y_left),
yaxis = "y1", type = 'scatter', mode = 'lines',
line = list(color = "#1f77b4"))
p_facets <- list()
for(v in y_right){
p_facets[[quo_name(v)]] <- p %>%
plotly::add_trace(y = v, name = quo_name(v),
yaxis = "y2", type = 'scatter', mode = 'lines') %>%
plotly::layout(yaxis = y_left_axparms,
yaxis2 = y_right_axparms)
}
p <- subplot(p_facets, nrows = length(y_right), shareX = TRUE)
return(p)
}
mtcars %>%
rowid_to_column() %>%
dual_axis_lines(rowid, mpg, cyl, disp, hp, facets = TRUE)
However, the resulting plots have all the secondary y-axis variables cluttered in the first facet.
The issue seems to be absent when I return p_facets lists that goes into subplot as each plot looks like below:
How can I fix this issue?
Okay, I followed the ideas given in this github issue about your bug.
library(rlang)
library(plotly)
library(tibble)
dual_axis_lines <- function(data, x, y_left, ..., facets = FALSE, axes = NULL){
x <- rlang::enquo(x)
y_left <- rlang::enquo(y_left)
y_right <- rlang::enquos(...)
## I removed some things here for simplicity, and because we want overlaying to vary between subplots.
y_left_axparms <- list(
tickfont = list(color = "#1f77b4"),
side = "left")
y_right_axparms <- list(
side = "right")
p <- plotly::plot_ly(data , x = x) %>%
plotly::add_trace(y = y_left, name = quo_name(y_left),
yaxis = "y", type = 'scatter', mode = 'lines',
line = list(color = "#1f77b4"))
p_facets <- list()
## I needed to change the for loop so that i can have which plot index we are working with
for(v in 1:length(y_right)){
p_facets[[quo_name(y_right[[v]])]] <- p %>%
plotly::add_trace(y = y_right[[v]], x = x, name = quo_name(y_right[[v]]),
yaxis = "y2", type = 'scatter', mode = 'lines') %>%
plotly::layout(yaxis = y_left_axparms,
## here is where you can assign each extra line to a particular subplot.
## you want overlaying to be: "y", "y3", "y5"... for each subplot
yaxis2 = append(y_right_axparms, c(overlaying = paste0(
"y", c("", as.character(seq(3,100,by = 2)))[v]))))
}
p <- subplot(p_facets, nrows = length(y_right), shareX = TRUE)
return(p)
}
mtcars %>%
rowid_to_column() %>%
dual_axis_lines(rowid, mpg, cyl, disp, hp, facets = TRUE)
Axis text the same color as the lines.
For this you would need two things. You would need to give a palette to your function outside of your for-loop:
color_palette <- colorRampPalette(RColorBrewer::brewer.pal(10,"Spectral"))(length(y_right))
If you don't like the color palette, you'd change it!
I've cleaned up the for-loop so it's easier to look at. This is what it would now look like now so that lines and axis text share the same color:
for(v in 1:length(y_right)){
## here is where you can assign each extra line to a particular subplot.
## you want overlaying to be: "y", "y3", "y5"... for each subplot
overlaying_location = paste0("y", c("", as.character(seq(3,100,by = 2)))[v])
trace_name = quo_name(y_right[[v]])
trace_value = y_right[[v]]
trace_color = color_palette[v]
p_facets[[trace_name]] <- p %>%
plotly::add_trace(y = trace_value,
x = x,
name = trace_name,
yaxis = "y2",
type = 'scatter',
mode = 'lines',
line = list(color = trace_color)) %>%
plotly::layout(yaxis = y_left_axparms,
## We can build the yaxis2 right here.
yaxis2 = eval(
parse(
text = "list(side = 'right',
overlaying = overlaying_location,
tickfont = list(color = trace_color))")
)
)
}

Modifying labels (x,y,z) in heatmap on plotly?

I want to rename labels in a heatmap. for example:
instead of the label says "x:", I want the label to say "Hour:"
instead of the label says "y:", I want the label to say "Day:"
Library(plotly)
p <- plot_ly(z = volcano, colors = colorRamp(c("red", "green")), type = "heatmap")
furthermore, it would be useful, for example if we use a transformation of data in order to intensify contrast, still the html interactive label show real data.
Example
What about
library(plotly)
dat <- expand.grid(x = 1:nrow(volcano), y = 1:ncol(volcano))
dat$z <- c(volcano)
plot_ly(height = 500) %>%
layout(autosize = FALSE,
xaxis=list(title = "Hour", titlefont = list(size=20)),
yaxis=list(title = "Day", titlefont = list(size=20))) %>%
add_trace(data = dat, x = ~x, y = ~y, z = ~z, type = "heatmap",
hoverinfo = 'text',
text = ~paste("Hour:", dat$x,
"<br> Day:", dat$y,
"<br> z:", dat$z))

Ordered bars on plotly

I'm trying to make a CPU Usage graph with Plotly and R, I want the max usage (100%, the blue bar) on top, and the other one on bottom, but when I try this code
plot_ly( x = cores, y = max, type = 'bar', name = 'Free') %>%
add_trace( y = data, name = 'Used') %>%
layout(
title = "CPU Usage",
font = list(family = 'Comic Sans MS'),
yaxis = list(title = 'Percent'),
xaxis = list(title = '', tickangle = -45),
barmode = 'stack')
})
It gives me the reverse, ordering the greater bar on bottom, and the orange one on top. I want to invert it.
I searched on some references but nothing was found about that...
We do not know your data but:
cores <- c("Average", "Core1", "Core2", "Core5")
Free <- c(65, 60, 80,50)
Used <- c(100-65, 40, 20,50)
data <- data.frame(cores, Free, Used)
plot_ly(data, x = ~cores, y = ~Used, type = 'bar', name = 'Used') %>%
add_trace(y = ~Free, name = 'Free') %>%
layout(yaxis = list(title = '%'), barmode = 'stack')

Plotly (via R): Increase width of tooltips/hover boxes

I use library(plotly) to draw a colored interactive bar chart in R. When the user hovers a bar with the mouse, little tooltips pop up and provide information about the name of the respective color group. How can I make this tooltip wider so that it can be used with longer names?
library(tibble)
library(plotly)
tibble(x = 1,
nam = paste('reasonably long name', LETTERS),
y = 1:26) %>%
plot_ly(x = ~x, y = ~y, color = ~nam, type = 'bar', hoverinfo = 'name') %>%
layout(showlegend = FALSE)
This is controllable via the layout.hoverlabel.namelength attribute. You can set it to any integer number of characters you wish. The default is 15. To display all characters regardless of the length set it to -1.
Using your example:
library(tibble)
library(plotly)
tibble(x = 1,
nam = paste('reasonably long name', LETTERS),
y = 1:26) %>%
plot_ly(x = ~x, y = ~y, color = ~nam, type = 'bar', hoverinfo = 'name') %>%
layout(showlegend = FALSE, hoverlabel = list(namelength = -1))
Reference: https://plotly.com/r/reference/#scatter-hoverlabel-namelength

Resources