1

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

the plot as it looks now

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!

2
  • 1
    Does this answer your question? How to round the hover information when using ggplotly? Commented Aug 18, 2023 at 8:50
  • Nope. :( round() does not work, regardless of the position, i.e., neither of !!sym(round(feature)) or round(!!sym(feature)) delivers a rounded tooltip. Commented Aug 18, 2023 at 8:55

1 Answer 1

2

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 geoms 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")

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Works neatly. Thanks a lot!
Can you tell me how to add a y value as well? When directly entering it similar to the x, I get the response "object 'y' not found". I succeeded to add the correct density value for each row to my dataframe, but I don't know how to fetch it from there. Nesting the y in aes() of ggplot() blows up my density plot. :/
No need to add a colum with the density value. Inside after_stat you can get the density value using density. See also this answer by me for some explanation: stackoverflow.com/questions/75988042/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.