I used ggplot2
and ggplotly
to compose a density chart of a given variable (population per census tract, in two groups). The tooltip shows six decimal places for the variable:
persons_per_census_tract: 16.684932
However, I want it to show integers:
persons_per_census_tract: 17
Code:
### create dummy data
# normal distribution
rnorm1 <- rnorm(200, mean=10, sd=3)
# dataframe with the urban/rural labels and normal distribution
data <- data.frame(spatial_type = rep(c("1: urban", "2: rural"), each = 200 / 2),
persons_per_census_tract = rnorm1)
# define a function to combine several histograms in one plot, inspired by
# https://stackoverflow.com/a/53680101
# here already defining some parts of the appearance (y axis, outline size, colour via scale_fill_manual)
plot_multi_histogram <- function(df, feature, label_column) {
plt <- ggplot(df, aes(x=!!sym(feature),
fill=!!sym(label_column)),
text=paste(scales::percent(!!sym(feature)), "persons/census tract")) +
scale_fill_manual(
values=c("#9BB7B0", "#2DC6D6"),
breaks=c("1: urban", "2: rural")) +
geom_density(alpha=.7, size = .2) +
scale_y_continuous(labels = scales::unit_format(scale = 100, unit = "%")) +
labs(x=feature, y="density")
plt <- plt + guides(fill=guide_legend(title=label_column))
# Convert ggplot to a plotly object
plt <- ggplotly(plt, tooltip=c(feature))
return(plt)
}
# revert factor order of spatial_type to determine rendering order
# https://stackoverflow.com/a/43784645
data$spatial_type <- factor(data$spatial_type, c("2: rural", "1: urban"))
# Apply the function to create the plot based on dummy data
density.p <- plot_multi_histogram(data, 'persons_per_census_tract', 'spatial_type')
# print the plot
plotly::ggplotly(density.p)
I've tried to include several options into the code that defines the function plot_multi_histogram <- ...
, e.g. scales::percent
text=paste(scales::percent(!!sym(feature)), "persons/census tract")
or as.integer
text=paste(as.integer(!!sym(feature)), "persons/census tract")
or sprintf() or round()
.
I suppose the rounding attempts fail because they are embedded in the function. Any ideas? Thx!
First issue is that you have set tooltip=feature
. Hence, the value for the tooltip is taken from the raw feature
column of your dataset. That's the reason why changing anything in text=...
has no effect. Second, you have put text=
outside of aes()
in ggplot()
. Well, in case of ggplot()
all arguments outside of aes()
will be silently ignored. If you want create a tooltip from a data column using !!sym()
you have to do that inside aes()
.
Unfortunately simply moving text=
inside aes()
will also not fix the issue as this works only fine in case of geom
s using stat="identity"
. Perhaps there is a more straightforward approach I'm not aware of. But one fix would be to set and format the tooltip text
using after_stat
and of course by setting tooltip="text"
in ggplotly
:
library(ggplot2)
library(plotly)
set.seed(123)
plot_multi_histogram <- function(df, feature, label_column) {
plt <- ggplot(df, aes(
x = !!sym(feature),
fill = !!sym(label_column)
)) +
scale_fill_manual(
values = c("#9BB7B0", "#2DC6D6"),
breaks = c("1: urban", "2: rural")
) +
geom_density(
aes(text = after_stat(
paste(
scales::number(x, accuracy = 1), "persons/census tract"
)
)),
alpha = .7, size = .2
) +
scale_y_continuous(labels = scales::unit_format(scale = 100, unit = "%")) +
labs(x = feature, y = "density")
plt <- plt + guides(fill = guide_legend(title = label_column))
ggplotly(plt, tooltip = "text")
}
data$spatial_type <- factor(data$spatial_type, c("2: rural", "1: urban"))
plot_multi_histogram(data, "persons_per_census_tract", "spatial_type")