It’s 2019 — Make Your Data Visualizations Interactive with Plotly
By: Jeff Hale
Tags: Technology, Towards Data Science, Data Science, Statistics, Data Visualization

Plotly allows you to make beautiful, interactive, exportable figures in just a few lines of code.

Plotly Express examples from Plotly announcement

However, without a map, the the path up Mt. Plotly 🗻 can be slow and frustrating.

Here are the stumbling blocks that hold back the adventurous as they are trying to make their way:

confusing initial setup to work offline without an account

lines and lines of code to write

out-of-date documentation

a plethora of different Plotly tools that are hard to keep straight (Dash, Express, Chart Studio, and Cufflinks)

After several starts up the trail, I’ve found the map, the gear, and the quick route to the top. In this article I’ll lead you up the mountain by showing you how to get started offline, how to make figures in a line of code and then tweak them, where to go for help, and which tool to use when.

Let’s start climbing. The view is worth, it. Trust me. 😃

Plotly

The company behind Plotly is also named Plotly. It has open-sourced a slew of interactive visualization products. It makes money by offering enhanced functionality for many products. It also offers private hosting for a fee. The company is based in Montreal, with an office in Boston.

plotly.py uses D3.js behind the scenes. Plotly has API wrappers for R, Julia, and many other language. Note that not all languages have all example docs available.

Instruction options in Plotly docs

We’ll be focussing on options that use Python in this article. I’m using Python 3.7 and the following library versions in this guide.

cufflinks 0.15

jupyterlab 0.35.5

plotly 3.8.1

plotly-express 0.1.7

Make sure you’re using cufflinks 0.15 (0.13 doesn’t play nicely with recent Plotly versions).

UPDATE May 2020: Plotly 4.7.1 is the is the latest version. Much, but not all of the following still applies with the new version. Note that the express module is imported as part of the plotly package.

plotly.py

You don’t need to create an account to use Plotly, contrary to how some document examples might make it seem. You don’t need to be online to use Plotly, either.

Install the vanilla plotly.py module in conda or with pip install plotly .

Import the module and configure it to work offline:

import plotly.offline as py py.init_notebook_mode(connected=False)

Now you won’t get an error that you need an account. We’re past the first obstacle on our way up the mountain. 😄

Here’s an example of an interactive Plotly figure of a globe that allows you to easily change the projection type and location with sliders. You can’t interact with the figure here due to Medium’s restrictions on file types, but you can interact with it in the docs.

Below is a lengthy Gist for the plotly.py code adapted from the docs needed to make this fancy figure.

Plotly objects consist of one or more data components and a layout component. Both have subcomponents. Most, but not all, of the formatting is controlled in the layout.

The main reason to avoid vanilla plotly.py is that the figure definitions are often verbose. Specifying lines and lines of code is slow and error prone. We definitely hit our second hurdle on our adoption path. Luckily we can usually take one of two alternate routes that we’ll explore in a minute.

If we do need to stay on the old plotly.py path, we’ll need to dig into the docs. The official documentation is pretty, but often leaves me searching for way too long to figure out how to adjust something.

Plotly does have a nice forum here and there are some helpful SO questions, but many examples aren’t updated to show plotly.py v3 code. Here’s the v3.0 migration guide which can help a bit. Make sure any examples you are looking for are using v3, or be prepared to translate them into v3.

The next two Plotly products we’ll look at provide high-level wrappers that simplify the plotly.py API. They can save you gobs of time if you’re working with Pandas. Let’s explore these alternate routes.

Forrest path

Express

Plotly Express was released in March 2019, and is in active development, with support for more charts on the way. The plan is to fold it into Plotly 4.0 in summer 2019.

Express can reduce the code required to make many Plotly figures from a Pandas DataFrames by a factor of 10. Express expects your DataFrame to arrive in Tidy format, where each row represents an observation and each column represents a variable.

Install Express with pip install plotly_express .

To use it in JupyterLab run the following in your terminal:

jupyter labextension install @jupyterlab/plotly-extension

Here’s the code to make a bar chart from a DataFrame, with the conventional Express import:

import plotly_express as px px.bar(my_df, x='my_x_column', y='my_y_column')

Viola! You’ve got a bar chart from your DataFrame (substitute your stuff where I have “my_” above).

You can adjust many values in the one-line figure definition. For example, add a title by changing your definition like this:

px.bar(my_df, x='my_x_column', y='my_y_column', title='My Chart Title")

If you want to dig in to a specific setting, you can return the underlying Plotly figure. Say you want to add text values to the bars on your bar chart. You need to save the automatically returned figure and reference its data properties. Here’s how you do it:

_my_fig = px.bar(my_df, x='my_x_column', y='my_y_column', title='My Chart Title') _my_fig.data[0].update(

text=my_df['my_y_column'],

textposition='inside',

textfont=dict(size=10)

) _my_fig.iplot()

Alert: I found the Express documentation! It didn’t rank near the top of my Google searches for my Plotly-Express-related searches, so I didn’t find it for a while. Now you have it. Enjoy! 😃

Express allows you to make many figure types quickly, but not all types you might want are available. For example, stacked bar charts aren’t currently an easy option. For those you’ll want to take the other route to the top of the mountain with Cufflinks.

The other path

Cufflinks

Cufflinks is very similar to Express, in that it’s a wrapper for the Plotly API to simplify working with Pandas. Cufflinks is a third-party open source project that’s been around for over four years.

Install with pip install cufflinks .

Import the module and configure the file for offline use.

import cufflinks as cf

cf.set_config_file(offline=True)

Many figure types require only a single line of code with Cufflinks. For example, stacked bar charts are a breeze.

Example cufflinks stacked bar chart

Here’s the code:

df = pd.DataFrame(np.random.rand(6, 3), columns=['A', 'B', 'C']) df.iplot(kind='bar', barmode='stack', title='Stacked Bar Chart with Random Data')

Note that you’ll use .iplot() to make your figures with Cufflinks.

Like Express, Cufflinks returns the underlying Plotly figure so you can make more fine-grained modifications. Unlike Cufflinks, you need to specify asFigure=True in your figure definition to return a figure. Then you can update the figure just like in Express. Here’s how that looks if you want to change the title and range of the yaxis.

my_fig = df.iplot(kind='bar', barmode='stack', title='Stacked Bar Chart with Random Data', asFigure=True) _fig.layout.yaxis = dict(title='Members', range=[0, 600])

Here are the Cufflinks Docs.

Unfortunately, some things aren’t doable with Cufflinks, such as scattergeo plots.

Comparison of the 3 Options

Here’s a comparison of code with similar layout for figures created with plotly.py, Express, and Cufflinks.

plotly.py

fig = {

'data': [

{

'x': df2007.gdpPercap,

'y': df2007.lifeExp,

'text': df2007.country,

'mode': 'markers',

'name': '2007'},

],

'layout': {

'title': "Example Scatter Plot with Vanilla plotly.py"

}

} py.iplot(fig)

Express

px.scatter(

df2007,

x="gdpPercap",

y="lifeExp",

title='Example Scatter Plot with Plotly Express'

)

That’s short and sweet! The default formatting is a bit different and you get the axes titles automatically. Let’s look at the same chart in Cufflinks.

Cufflinks

df2007.iplot(

kind='scatter',

mode='markers',

x='gdpPercap',

y='lifeExp',

title='Example Scatter Plot with Cufflinks'

)

That’s very similar code to Express, but the figure has slightly different defaults.

Both Express and Cufflinks definitely save you keystrokes. ⌨️ This is especially true with many more complicated charts. 😃

Let’s look at how to return and access the underlying plotly figures.

Updating Cufllinks and Express Figures

Let’s access the layout for the figure created by Cufflinks and add axes titles.

fig = df2007.iplot(

kind='scatter',

mode='markers',

x='gdpPercap',

y='lifeExp',

asFigure=True,

title='Example Scatter Plot with Cufflinks - Access Underlying Figure'

) fig.layout.xaxis.title = "GDP per Capita"

fig.layout.yaxis.title = "Life Expectancy" fig.iplot()

Here’s how you do the same thing with Express. Recall that with Express, you don’t need to specify asFigure=True .

fig = px.scatter(

df2007,

x="gdpPercap",

y="lifeExp",

title='Example Scatter Plot with Plotly Express - Access Underlying Figure'

) fig.layout.xaxis.title = "GDP per Capita"

fig.layout.yaxis.title = "Life Expectancy" fig.iplot()

You can access the first data trace to add text labels like this:

fig.data[0].update(

text=df2007['gdpPercap'],

textposition=’inside’,

textfont=dict(size=10)

)

Choosing among plotly.py, Express, and Cufflinks

The space really is confusing. At one point not long ago, I thought I was using Express in one part of a project, when I was using Cufflinks! 🤦‍♂

I’m a big fan of the Zen of Python’s one clear way: “There should be one — and preferably only one — obvious way to do it.” Two ways leads to research time, choice fatigue, and errors.

Unfortunately there isn’t a single high-level API to make every figure type right now. However, I definitely would use Cufflinks or Express over vanilla plotly.py whenever possible.

I suggest you check the Express and Cufflinks docs when you want to build a figure. Remember that Express requires tidy DataFrames, while Cufflinks is more flexible. Use whichever of the two libraries fits your needs and has formatting closest to what you want. Cufflinks is where I look first.

The default formatting between the two libraries can be quite dramatic. For example, with some random data for X, Y, and Z columns in a DataFrame you can get this with this Cufflinks code:

df.iplot(kind=’scatter’, mode=’markers’, x=’X’, y=’Y’, title=’Random Data’, categories=’Z’)

Cool Default Cufflink Scatter Plot

or this with this Express code:

px.scatter(df, x=’X’, y=’Y’, color=’Z’, title=’Random Data’)

Different Presets with Express

That’s quite a difference!

Saving Files

Once you have a figure created, you can mouse-over it and click on the camera icon to export it as a .png file or click on the Export to plot.ly link to save the interactive image to Plotly’s servers.

Alternatively, you can download files in interactive HTML format like this:

py.offline.plot(my_fig, filename=’my_example_file.html’)

If you need more image formats, you can use Plotly’s orca package to download files in formats including .png, .jpg, and .pdf. You’ll need to install orca first. The package is not currently available on pypi.org, so you can’t pip install it. You can install it via conda or you can install os-specific versions from the orca GitHub page. Then you don’t need to import the orca library. Read more about orca here.

Here’s the code to create a .png file once you have orca installed.

import plotly as plotly

plotly.io.write_image(fig, file='my_figure_file.png', format='png')

As you can see, there are a few ways to get your figures out of Plotly. 😃

Let’s briefly touch on two other components of the Plotly ecosystem so that you know what’s what.

Dash

With Plotly Dash you can use Python to make web app dashboards for your team or the world. There’s a free open source version with nearly 9,000 GitHub stars as of May 1, 2019. There’s a suite of Dash add-ons offered by Plotly. I haven’t used Dash much. Maybe that will be a focus of a future article. Follow me to make sure you don’t miss it. 😄

Chart Studio

Plotly Chart Studio makes it easy to create or edit your charts in the browser. Plotly bills it as “the world’s most sophisticated editor for creating D3.js and WebGL charts. No coding required.” There’s a free version, but annual pricing starts at $99 if you want to save private chart files.

Now that we’ve made it to the top of Mt. Plotly, let’s take a quick look at other data visualization mountains in the Python range.

Bonus: Other Python Data Viz Options

This article isn’t meant to be an exhaustive look at data visualization options, but I’ll mention a few other important options for data scientists to know about, so you have a fairly comprehensive lay of the land.

The old school way to make visualizations in Python is with the vanilla Matplotlib API.

The Pandas Matplotlib API is nice for quick plots. It creates regular Matplotlib objects.

Seaborn is a great high level wrapper around Matplotlib that lets you quickly make many types of statistical visualizations. Unfortunately, these options aren’t interactive and are built on a 15-year-old Matplotlib foundation that isn’t super easy to use.

Bokeh is a competitor to Plotly. It’s open source, interactive, and works with Python.

Holoviews is a higher-level wrapper around MatplotLib, Bokeh, and now Plotly. I know folks who like Holoviews.

R folks love Shiny from RStudio. It lets’ R users create interactive web application visualizations.

Tableau and Microsoft PowerBI are two other popular drag and drop data visualization creation options that integrate with Python. Tableau is really nice, but requires you to pay money to keep your work private.

I find PowerBI a bit less intuitive, but it’s also very powerful and very popular.

Most all the interactive figure software listed above is using D3.js under the hood. It’s super popular.

Wrap and Resources

If you’re a data scientist, I encourage you to check out Plotly. It’s a modern toolbox for making interactive visualizations. From the top of the mountain, it seems the Plotly juggernaut isn’t likely to be slowed down anytime soon.

Maybe eventually there will be one clear way to make everything you want using Ploly’s high level API options. For now, I suggest you use Pandas with Cufflinks or with Express whenever you can to save time and make awesome visualizations.

Here are some good Plotly resources:

Will Koehrsen has a nice guide to getting started with Cufflinks here.

Here’s a talk by Jon Mease, the plotly.py lead developer, showing what you can do with plotly.py v3.0 in JupyterLab. You can get help in your notebook and make some very cool widgets. If you haven’t switched to running your Juypter notebooks in JupyterLab yet, this might be the push you need. 😃

PSA: Whenever you are using color, think about accessibility for folks with color blindness. It’s easy to use a color-blind-friendly palette. Here’s one I adopted from ggplot.

Color swatch

color_list = ["#E69F00", "#56B4E9", "#009E73", "#F0E442", "#D55E00", "#0072B2", "#CC79A7"]

I write about data science, Python, and DevOps. Check out my articles here and sign up for my newsletter if you’re into that stuff.

Happy Plotlying!