How to Keep My Subtitles When I Use Ggplotly()

How do I keep my subtitles when I use ggplotly()

This helped me, Subtitles with ggplotly. Seems any text such as annotations or subtitles added to ggplot must be put after the ggplotly function into a layout function.

plot <- retention_cohorts %>% 
ggplot(aes(relative_week, round(percent,2), label=relative_week)) +
geom_line() +
scale_y_continuous(labels = percent) +
scale_x_continuous(breaks = seq(1,24,4),
labels = seq(1,6)) +
geom_text(nudge_y = .02) +
labs(y = "Customers with at least One Purchase",
x = "Relative Month") +
theme_light()

ggplotly(plot) %>%
layout(title = list(text = paste0('Purchasing Retention Analysis',
'<br>',
'<sup>',
'Customers who order at least one item each week','</sup>')))

Create a ggplotly object with a subtitle

I'd suggest using ggtitle and hjust = 0.5:

Edit: using plotly::layout and a span tag to create the title:

library(data.table)
library(ggplot2)
library(plotly)
library(lubridate)

dt.allData <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
DE = rnorm(365, 4, 1), Austria = rnorm(365, 10, 2),
Czechia = rnorm(365, 1, 2), check.names = FALSE)

## Calculate Pearson correlation coefficient: ##
corrCoeff <- cor(dt.allData$Austria, dt.allData$DE, method = "pearson", use = "complete.obs")
corrCoeff <- round(corrCoeff, digits = 2)

## Linear regression function extraction by creating linear model: ##
regLine <- lm(DE ~ Austria, data = dt.allData)

## Extract k and d values for the linear function f(x) = kx+d: ##
k <- round(regLine$coef[2], digits = 5)
d <- round(regLine$coef[1], digits = 2)
linRegFunction <- paste0("y = ", d, " + (", k, ")x")

## PLOT: ##
p1 <- ggplot(data = dt.allData, aes(x = Austria, y = DE,
text = paste("Date: ", date, '\n',
"Austria: ", Austria, "MWh/h", '\n',
"DE: ", DE, "\u20ac/MWh"),
group = 1)
) +
geom_point(aes(color = ifelse(date >= now()-weeks(5), "#419F44", "#F07D00"))) +
scale_color_manual(values = c("#F07D00", "#419F44")) +
geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE, color = "#007d3c") +
# ggtitle(label = paste("My pretty useful title", '\n', "\u03c1 =", corrCoeff, '\n', linRegFunction)) +
theme_classic() +
theme(plot.title = element_text(hjust = 0.5)) +
theme(legend.position = "none") +
theme(panel.background = element_blank()) +
xlab("Austria") +
ylab("DE")

# Correlation plot converting from ggplot to plotly: #
# using span tag (directly in control of font-size):
span_plot <- plotly::ggplotly(p1, tooltip = "text") %>% layout(
title = paste(
'<b>My pretty useful title</b>',
'<br><span style="font-size: 15px;">',
'\u03c1 =<i>',
corrCoeff,
'</i><br>',
linRegFunction,
'</span>'
),
margin = list(t = 100)
)
span_plot

Edit: added the sup alternative as per this answer

# using sup tag:
sup_plot <- plotly::ggplotly(p1, tooltip = "text") %>% layout(
title = paste(
'<b>My pretty useful title</b>',
'<br><sup>',
"\u03c1 =<i>",
corrCoeff,
'</i><br>',
linRegFunction,
'</sup>'
),
margin = list(t = 100)
)
sup_plot

result

Here you can find some related information in the plotly docs.

Plot subtitle is lost when plot is diplayed with ggplotly()

library(ggplot2)
p <- ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
geom_boxplot()
library(plotly)
p <- p + labs(title = "Effect of Vitamin C on Tooth Growth",
subtitle = "Plot of length by dose",
caption = "Data source: ToothGrowth")
ggplotly(p)%>%
layout(title = list(text = paste0('Effect of Vitamin C on Tooth Growth"',
'<br>',
'<sup>',
'Plot of length by dose','</sup>')))

This works let me know if it fixes your issue

Add dynamic subtitle using ggplot

You should use function bquote() instead of expression() to use titles that are stored as variables. And variable names should be placed inside .()

plot.title = 'TITLE'
plot.subtitle = 'SUBTITLE'

ggplot(mtcars,aes(disp,mpg))+geom_point()+
ggtitle(bquote(atop(.(plot.title), atop(italic(.(plot.subtitle)), ""))))

Sample Image

UPDATE - ggplot2 version 2.2.1

The latest ggplot2 version now can produce subtitles directly, so you don't have to use bquote() and expression(). The result is atchieved with argument subtitle = of function labs().

ggplot(mtcars,aes(disp,mpg))+geom_point()+
labs(title = plot.title,subtitle = plot.subtitle) +
theme(plot.subtitle = element_text(face = "italic"))

How to give subtitles for subplot in plot_ly using R

The title attribute in layout refers to the title for the entire plotting surface, so there can only be one. However, we can use text annotations to create "titles" for your subplots, for example:

p <- subplot(
plot_ly(economics, x = date, y = uempmed)%>%layout(showlegend = FALSE),
plot_ly(economics, x = date, y = unemploy)%>%layout(showlegend = FALSE),
margin = 0.05
)
p %>% layout(annotations = list(
list(x = 0.2 , y = 1.05, text = "AA", showarrow = F, xref='paper', yref='paper'),
list(x = 0.8 , y = 1.05, text = "BB", showarrow = F, xref='paper', yref='paper'))
)

How to align title and subtitle in ggplot2 when generated via expression

From the "it's stupid but it works" file, you can add spaces to the right of center to force left alignment. The right number of spaces could be determined using math, but I couldn't see how to pass a string variable back into atop.

# Chart
ggplot(data = mtcars) +
geom_boxplot(aes(y = wt, x = as.factor(am)), fill = "gray87") +
xlab("AM") + ylab("WT") + theme_gdocs() +
ggtitle(expression(atop("WT by AM ",
atop(italic("Some crucial note that has to be here"), "")))) +
theme(axis.title.y = element_text(angle = 90),
axis.ticks = element_line(colour = "black", linetype = "solid", size = 0.5),
panel.grid = element_line(colour = "gray"))

Sample Image

How to add captions in each individual plot using facet_grid in R?

Generally-speaking for plot captions on multi-faceted plots:

  • If you want a single caption which is below alll plots, you should use theme(plot.caption = ...).

  • If you want the same caption to appear below each facet, you can do this using annotate() and turn clipping off.

  • If you want to have different captions to appear below each facet, you will need something capable of being mapped to a dataset (so you can specify the different text per facet). In this case, I would recommend using geom_text() and doing a clever bit of formatting to fit in the caption.

  • An alternative to have different caption per plot would be create individual plots with captions and link them together via grid.arrange() or patchwork or cowPlot()...

Here's the example of the third case using geom_text() and mtcars. I hope you can apply this to your own dataset.

The basic plot

Here's the basic plot we'll use for adding a caption:

library(ggplot2)
p <- ggplot(mtcars, aes(qsec, mpg)) + geom_point() +
facet_wrap(~cyl)

Sample Image

Caption Data frame

To make the caption plot, we first need to define the text per each facet. It's best to do this in a separate data frame from your bulk data. This ensures that there is not any overplotting of the text geom (drawing in the same place multiple times), since one text geom is drawn per observation in a data frame. Here's our dataframe for captions:

caption_df <- data.frame(
cyl = c(4,6,8),
txt = c("carb=4", "carb=6", "carb=8, OMG!")
)

Plotting with captions

To make the plot, we need to adjust a few things to our plot.

  • Add the caption. Add a geom_text() and map to caption_df. We'll map the text, but the position will be fixed in x and y. The x value is set to be the minimum of our original data, but we could set that manually too. The y value needs to be set a value that would place it below the original plot.

  • Confine the limits of the plot. Since we place our text geom below the original plot area, if we did not confine the limits of the plot area, ggplot2 would just expand the y limits to fit the new text. We need to keep the original y limits to ensure the y value of the geom_text() we add stays below this area.

  • Turn off clipping. In order to actually see the new captions, you need to turn off clipping. You can do this in any of the coord_*() functions, so we'll use coord_cartesian() to do this and set the y limits.

  • Increase lower margin. To ensure we see the caption in the final image, we need to increase the margin below the plot via theme(plot.margin=...).

Here's the final result of all that.

ggplot(mtcars, aes(qsec, mpg)) + geom_point() + facet_wrap(~cyl) +
coord_cartesian(clip="off", ylim=c(10, 40)) +
geom_text(
data=caption_df, y=5, x=min(mtcars$qsec),
mapping=aes(label=txt), hjust=0,
fontface="italic", color="red"
) +
theme(plot.margin = margin(b=25))

Sample Image



Related Topics



Leave a reply



Submit