How to Turn Your ggplot2 Visualization into an Interactive Tweet

Side-by-side comparison of static plot versus interactive tweet

I love how the modern Web and free software are like Lego blocks you can combine in myriad ways to create new and interesting things. While working on a recent analysis of climate policy leadership records for 2020 presidential candidates, I decided to try mashing together a few cool technologies I’d worked with to see if I could create a simple pipeline from my preferred open source data visualization library, Hadley Wickham’s ggplot2, to interactive data visualizations people could explore right inside their Twitter timelines.

Not only does it work, but you don’t even need to write any JavaScript to accomplish it thanks to all the great free software tools out there.

The Tool Chain

ggplot2
Perfect your one-of-a-kind data visualization using the grammar of graphics
plotly R package
Easily convert your ggplot2 object into a plotly.js interactive chart
htmlwidgets R Package
Save your interactive chart as a standalone HTML page
WordPress
Write up your report and host your standalone interactive chart
Meta Tag Manager WordPress Plugin
Configure your post for interactive twitter previews
Twitter Player Cards
Any time a link to your blog post is shared on Twitter, it will include an interactive preview card

The End Product

Here’s an example of an interactive data tweet (it even works when you embed that tweet in other sites like this). Click the play button to start interacting.

Twitter’s in-timeline player cards currently only work when viewed in a Web browser. This works great on both desktop and mobile, but mobile users viewing via the Twitter native app will see your visualization open in a browser window instead.

The Process

Here are the steps to take to convert your visualization into an interactive tweet.

Prerequisites

This is what you’ll need to complete the tutorial:

  • An installation of R with the ggplot2 and plotly packages
  • A WordPress site or other web host with SSL where you can upload files

Convert ggplot2 to plotly

static_plot <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width, color = Species)) +
  geom_point()
interactive_plot <- plotly::ggplotly(static_plot)
interactive_plot

The plotly R package makes this step ridiculously simple. Save your ggplot to an object pass it into a call to the ggplotly function. Print the output of that function to see your interactive plot in the RStudio viewer or inline in an RMarkdown document. This method is remarkably competent at converting most ggplot features and themes automatically, but, if it doesn’t look exactly right, checkout the troubleshooting section below.

Export plotly widget to HTML

interactive_plot$sizingPolicy$padding <- "0"
htmlwidgets::saveWidget(
  interactive_plot, "index.html", libdir = "lib",
  title = "Iris Flowers Interactive",
  selfcontained = FALSE
)

The plotly package is powered by htmlwidgets, so it is easy to export it as HTML and JavaScript with the saveWidget function. Before exporting, I’ve changed the sizing parameters for the widget to override the default 40 pixel padding as this would take up too much of the limited space available in an interactive tweet. I’m also using selfcontained = FALSE. This saves and links the JavaScript dependencies in the folder specified by libdir. While making the upload a little more complicated, using separate files greatly improves loading time as the alternative results a massive (>3MB) HTML file.

Add to WordPress

I’m using WordPress because I already had a blog setup, but any hosting (even static HTML hosting) is fine as long as it supports secure connections and you are able to edit the meta tags in the head of your post page. This step is simply uploading your newly exported standalone visualization to be hosted on your Web server. If your provider includes a control panel with a file manager, you can use that. Otherwise you can transfer it via FTP using free software such as FileZilla.

Make sure to choose an upload location that is public. I created a folder named embeds within wp-content/uploads to store all of my interactive visualizations.

Create a new folder for this visualization, iris in this case, and upload the index.html file along with the entire lib folder form your R working directory. If using FileZilla, it should look similar to this:

Upload your HTML file and lib folder from your R working directory to a public directory on your web host

After uploading, you should be able to view your interactive chart by visiting https://[your domain]/wp-content/uploads/embeds/[your folder]/. For example, https://datatitian.com/wp-content/uploads/embeds/iris/. Keep this link handy for the next step.

Configure Your Post

To enable the Twitter player card, you need to add specific meta tags to the post page. I was not able to find a WordPress plugin that handled player card metadata, so I just used the Meta Tag Manager plugin to add them manually. Once enabled, this plugin adds a simple interface to the bottom of your post editor in WordPress admin.

Here are the tags you must provide to enable to player card:

Name ValueContent Value DescriptionContent Value Example
twitter:cardCard type. Must be “player”player
twitter:siteYour twitter handle@Datatitian
twitter:titlePreview card title textInteractive Data Tweet Tutorial
twitter:descriptionPreview card description textHow to Turn Your ggplot2 Visualization into an Interactive Tweet
twitter:playerURL for the standalone visualization (from the previous step)https://datatitian.com/wp-content/uploads/embeds/iris/
twitter:player:widthPreferred with in pixels517
twitter:player:heightPreferred height in pixels408
twitter:imagePreview image to show before activation[link to the featured image of your post]

For each entry, add a meta tag of type “name” with the name value and content value according to the table. More information about the tags is also available in the official Twitter documentation.

You’ll probably want to include your interactive visualization in your blog post as well, and that can be done simply by adding an iframe with the same source you used for the twitter player. To do this, add a “custom HTML” block to your post, paste in the code below, and update the src to point to your visualization

<iframe width="800" height="600" src="https://datatitian.com/wp-content/uploads/embeds/iris/"></iframe>

It will appear like this in your post:

That’s it! Now when you publish your post and link to it in a tweet, your audience will be able to explore the data right from the comfort of their timelines. You can double check that everything is working before tweeting using the Twitter Card Validator. Paste your post link in there and you should see your fully interactive tweet. If not, check the troubleshooting section below.

Troubleshooting and Tweaking

Here are the problems and solutions I’ve encountered so far. If you have a problem not listed here, leave a comment and we’ll figure it out.

Wrong twitter card type / missing play button

If your link generates a normal image preview card on Twitter instead of the interactive player card, you probably have a WordPress plugin that is adding additional Twitter meta tags to your post that conflict with the player settings. You’ll need to disable that plugin for this post so it doesn’t override your custom meta tags.

It’s not very “interactive” on iOS / mobile Firefox

The published CRAN version of plotly for R links to a older version of the main plotly library, and I’ve found that tapping on points to inspect them doesn’t work on mobile Safari or Firefox. The good news is the GitHub version is updated and does work! You can install the updated (pre-release) version using devtools:

devtools::install_github("ropensci/plotly")

The legend titles are misplaced

One area where ggplotly isn’t quite perfect is in aligning the legend titles with the legends. You can manually position legend titles by removing the automatic ones and adding them as annotations. Tweak the x and y values until the placement is correct.

interactive_plot <- plotly::ggplotly(
  static_plot + guides(color = guide_legend(""))
)%>%
  add_annotations(text = "Species",
                  xref = "paper", yref = "paper",
                  x = 1.03, xanchor = "left",
                  y = 0.93, yanchor = "bottom",
                  legendtitle = TRUE, showarrow = FALSE)

The embedded interactive in my post is not mobile responsive

I used fixed width and height on the iframe for simplicity in the tutorial, but you can improve the display on varying device sizes with some simple CSS. First, add this class definition to your WordPress CSS (Appearance -> Customize -> Additional CSS)

.cl-interactive-embed {
	width: 800px;
	height: 600px;
	max-height: 90vh;
	max-width: 100%;
}

Then alter your iframe tag to use this class instead of the fixed dimensions.

<iframe class="cl-interactive-embed" src="https://datatitian.com/wp-content/uploads/embeds/iris/"></iframe>

Could I embed anything I wanted, like a full shiny app?

No. Twitter has guidelines for the use of the player card, and a full interactive data app would go well beyond them.

Rather not do it yourself?

I’m available for consultation if you need help understanding your data data and wowing clients with world-class data visualizations. Submit your contact info below to get started.

Consultation Inquiries

How to Turn Your ggplot2 Visualization into an Interactive Tweet

5 thoughts on “How to Turn Your ggplot2 Visualization into an Interactive Tweet

  1. Will,
    Excellent post!

    Q:
    Any way to have ggplotly()
    ALWAYS show the spikelines in the plot,
    as you hover the mouse over the iris scatter points?
    ie:
    – Is there a ggplotly() function parameter / argument
    to specify that?.

    Thanks!
    SFdude
    San Francisco

    1. Everything looks right in your tags and player, but the validator error indicates a problem the the twitter:player url. Perhaps they have banned GitHub pages as a source. I’ll test if I can get it to accept a github.io player link and report back

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to top