12 Editing views for publishing

Numerous layout components of a plotly graph can be directly manipulated, including annotation text and placement (more on this in section 17.2.3). In addition, the download (aka, toImage) button can be customized to export a static version to different file types including: svg, png, jpeg, and webp. Since svg can be easily converted to pdf, this effectively means we can edit a graph in a browser to perform touch-ups, then export to a high-quality pdf. At least currently, this workflow is recommended over first exporting to pdf (via orca()) then using Adobe Illustrator to manipulate the vectors, especially for adjusting the placement of annotations.

Figure 12.1 demonstrates this workflow on a choropleth map of estimated income in Minnesota by county where the top 10 counties by total income are labeled.19 For visuals like this, automated algorithms for placing the labels may not yield polished results, so it can be nice to have the option to adjust the placement manually. Although pressing ‘download plot’ exports a static version of the current state of the plot, there currently isn’t an official way to save the state of these manual edits in the HTML version. You could, however, create a shiny app that listens to the 'plotly_relayout' event to obtain the new annotation positions (see, for example, Figure 17.5) and translate that information into code.

Click to show code


# obtain geographical information for each county in MN
mn_sf <- us_counties(states = "MN")

# get income information for each county in MN
mn_income <- get_acs(geography = "county", variables = "B19013_001", state = "MN") %>%
    NAME = sub("County, Minnesota", "", NAME),
    county = reorder(NAME, estimate),
    color = scales::col_numeric("viridis", NULL)(estimate)

# find center of each county (for placing annotations)
mn_center <- mn_sf %>%
  st_centroid() %>%
    x = map_dbl(geometry, 1),
    y = map_dbl(geometry, 2)

# get top 10 counties by income with their x/y center location
top10labels <- mn_income %>%
  top_n(10, estimate) %>%
  left_join(mn_center, by = c("GEOID" = "geoid"))

# the map and top 10 county labels
map <- plot_ly() %>%
    data = left_join(mn_sf, mn_income, by = c("geoid" = "GEOID")),
    color = ~I(color),
    split = ~NAME,
    stroke = I("black"),
    span = I(1),
    hoverinfo = "none"
  ) %>%
    data = select(top10labels, NAME, x, y),
    text = ~NAME,
    x = ~x,
    y = ~y

# the dot-plot
bars <- ggplot(mn_income, aes(x = estimate, y = county)) +
  geom_errorbarh(aes(xmin = estimate - moe, xmax = estimate + moe)) +
  geom_point(aes(color = color), size = 2) +

# make manual edits in the browser, then click the 
# 'toImage' button to export an svg file
ggplotly(bars, dynamicTicks = TRUE, tooltip = "y", height = 8 * 96, width = 11 * 96) %>%
  subplot(map, nrows = 1, widths = c(0.3, 0.7)) %>%
  layout(showlegend = FALSE) %>%
    edits = list(
      annotationPosition = TRUE,
      annotationTail = TRUE,
      annotationText = TRUE
    toImageButtonOptions = list(format = "svg")

FIGURE 12.1: Estimated total income by county in Minnesota. The top 10 counties are labeled with editable annotations. After manually adjusting the placement of county labels in a web browser, and zooming in on the top 10 counties in the dot plot, the ‘download plot’ button is used to export to svg.

After pressing the “download plot” button to export svg, then the rsvg package can be used to convert the svg to pdf (Ooms 2018).

# This is the directory that my browser places downloads...
# you may have to change this to your download directory
download_dir <- "~/Downloads/"
withr::with_dir(download_dir, rsvg::rsvg_pdf("newplot.svg", "mn.pdf"))


Ooms, Jeroen. 2018. Rsvg: Render Svg Images into Pdf, Png, Postscript, or Bitmap Arrays. https://CRAN.R-project.org/package=rsvg.

  1. Yes, this is essentially a population map. A more informative visual would show income per person within a given county. I decided against showing the more informative version so the code would be more concise.