Plotly Caption after Download Plot as PNG

I've found some great posts on creating Plotly captions with annotations, and MS Copilot AI has been a tremendous help. However, I'm facing an issue: I want the annotation to be displayed only when the plot is downloaded as a PNG. While I can display the annotation all the time, which allows it to be included in the downloaded plot, it makes the plot very busy. Since this is in a Quarto book, and I already reference the figure with Quarto syntax, I'd prefer to show the annotation only in the downloaded plot. This way, if the plot is downloaded and used elsewhere, the data source and designer can be referenced with the static plot.

library(ggplot2)
library(plotly)

# Function to wrap text by inserting <br> tag after every 20 characters
wrap_text <- function(text, max_length = 20) {
  wrapped_text <- ""
  for (i in seq(1, nchar(text), by = max_length)) {
    wrapped_text <- paste0(wrapped_text, substr(text, i, i + max_length - 1), "<br>")
  }
  return(wrapped_text)
}

# Original annotation text
annotation_text1 <- "Designed by xyz"
annotation_text2 <- "Data Souce SUPPPPPPPPPPPPPPPPPPPPPPPPEEEEEEEEEEEEERRRRRRRRRRRRRRRRLLLLLLLLLONNNNNNNNNGGGGGGGGGGG"

# Wrap the annotation text
wrapped_annotation_text1 <- annotation_text1
wrapped_annotation_text2 <- wrap_text(annotation_text2)

# Create a ggplot object
p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point()

# Convert ggplot to plotly and add multiple annotations with wrapped text
plotly_plot <- plotly::ggplotly(p) |>
  plotly::layout(
    margin = list(
      l = 50,
      r = 50,
      b = 100,
      t = 50
    ),
    legend = list(
      orientation = 'h',  # Horizontal orientation
      xanchor = 'center', # Center the legend with respect to the x position
      yanchor = 'bottom', # Anchor the legend at the bottom
      x = 0.5,            # Center the legend on the x-axis
      y = -0.5,           # Position the legend below the x-axis
      bgcolor = "#E2E2E2",
      bordercolor = "#FFFFFF",
      borderwidth = 1,
      title = list(text = "") # Hide the legend title
    ),
    annotations = list(
      list(
        x = 1,
        y = -0.1,
        text = wrapped_annotation_text1,
        xref = 'paper',
        yref = 'paper',
        showarrow = FALSE,
        xanchor = 'right',
        yanchor = 'auto',
        xshift = 0,
        yshift = 0,
        font = list(size = 6)
      ),
      list(
        x = 0,
        y = 0.2,
        text = wrapped_annotation_text2,
        xref = 'paper',
        yref = 'paper',
        showarrow = FALSE,
        xanchor = 'left',
        yanchor = 'auto',
        xshift = 0,
        yshift = 0,
        font = list(size = 6)
      )
    )
  ) |>
  plotly::config(
    toImageButtonOptions = list(
      format = "png", # Specify the file format
      filename = "custom_plot_nameTest" # Specify the file name
    )
  )

# Display the plot
plotly_plot

Aside from adding JavaScript, is there a way to pass arguments to a Plotly function that would add captions to the plot only after it is downloaded as an image? I want the captions to be saved in the downloaded plot but not displayed when the Plotly plot is initially shown.

Thank you

Good evening,

I decided to use the X-axis for the data source since ggplot can pass the X-axis to plotly, but not the caption. While annotations are useful, I wanted a solution that didn't require customizing each figure individually. By using the X-axis to display the data source, I ensured that the information is included without detracting from the plot. I also set the text color to light grey so it provides necessary details about the plot designer and data source without drawing too much attention. This way, even if someone takes a screenshot instead of downloading the plot as a PNG, proper recognition is still given.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.