Beautiful Data Visualization Made Easy with Plotly

Introduction to Plotly graph_objects

Marco Sanchez-Ayala
The Startup
Published in
5 min readFeb 16, 2020

--

I’ve recently grown especially fond of Plotly after being inspired by André Sionek’s post on how to make award-winning data visualizations. I was immediately captivated by the modern aesthetics that Plotly makes quite easy to implement. Below is a web app I created using Dash, Plotly’s open-source framework for creating interactive dashboards, which uses exclusively Plotly-generated visuals.

What is Plotly?

Plotly is an open-source data visualization library for Python and R written in JavaScript, making graphs inherently interactive. They can be modified tremendously and are easily exported as images, HTML, etc. for seamless integration into a number of applications.

Why should you use Plotly?

It ultimately comes down to your preference. Other popular libraries such as Matplotlib, Seaborn, ggplot, or Altair just don’t quite do it for me! There’s something about Plotly’s out-of-the-box visuals that just pop a little more. Furthermore, Plotly comes with a very wide variety of possible graph types, many of which can also be animated. Lastly, the fact that any plots you create with Plotly in, say a Jupyter Notebook, can be essentially copy-and-pasted into a Dash app is incredibly helpful for quick implementation of a dashboard. For more reasons why Plotly is awesome, check out this blog post by Moorissa Tjokro.

Documentation

Plotly offers vast documentation covering many cases for implementation of different graph types. However, most of the useful parts of the documentation exist almost entirely as examples, making the learning curve a little steeper than necessary in my opinion. Thus, I’d like to offer some tips for getting started.

Installation

Install with pip or conda:

$ pip install plotly==4.5.0$ conda install -c plotly plotly=4.5.0

Refer to Plotly’s documentation if you experience issues.

Making graphs

First, it’s important to understand how Plotly generates figures. The following is taken directly from the documentation:

The goal of plotly.py is to provide a pleasant Python interface for creating figure specifications for display in the Plotly.js JavaScript library. In Plotly.js, a figure is specified by a declarative JSON data structure, and so the ultimate responsibility of plotly.py is to produce Python dictionaries that can be serialized into a JSON data structure that represents a valid figure.

Now, there are a few submodules that Plotly has to allow you to create visualizations:

  • express: A high-level interface for data visualizations. Good for quick visualizations, but data often needs to be structured in certain ways that otherwise can require confusing manipulation in pandas. There is also significantly less documentation available for express. I’d stay away from this unless your data is in very similar formats to the examples in the documentation. Express offers a fraction of the graphs possible with graph objects.
  • io: A low-level interface for displaying, reading and writing figures. Good if your data is already in the required JSON format. I’m not sure this is really that practical though unless you’re dealing with a graph objects graph that was exported as a JSON file.
  • graph_objects: A low-level interface to figures, traces and layout. My go-to. Highly customizable with a crazy number of possible graph types.

Let’s look at an example of how I like to structure my graph objects using Python.

This example, although quite simple, will touch on almost all of the most important fundamentals needed to create Plotly visualizations.

The framework

We follow these basic steps:

  1. Load data (optional if previously done)
  2. Instantiate a Figure object
  3. Add traces
  4. Update the figure layout

Let’s dissect the code to learn a little more.

1. Load data

x = np.arange(0,11,1)
y1 = x**2
y2 = x**3

I generate data to display y = x^2 and y = x^3 using numpy.

2. Instantiate a Figure object

fig = go.Figure()

I instantiate an empty graph_objects Figure object. I do this mainly for easier readability in subsequent lines. Some will pass a Scatter object (or any other type of trace) directly as a parameter when instantiating the Figure object as such: go.Figure(go.Scatter()). This gets messy though if we end up adding multiple traces into this figure.

3. Add traces

for y in [y1, y2]:
fig.add_trace(go.Scatter(
x=x,
y=y
)
)

Traces are simply individual data sets being plotting on a given Figure object.

Let’s ignore the loop for now. The basic idea is to call add_trace() to instantiate a Scatter object into the figure where I specify what the x and y values will be. This is the command that generates each line in the final output. Scatter is just one type of trace. There exist many more like Bar and Box.

Going back to the loop, we see I iterate over a list of the two traces I want to add. In the current case, we’re just dealing with two numpy arrays that will be plotted against the x array, so I put them in the same loop rather than writing out each add_trace() call explicitly.

There are a number of other parameters to include within Scatter such as line_color or name, which sets the display name for that trace in the legend. These can be found in the Plotly documentation.

Lastly, I find myself pretty much always plotting straight from a pandas DataFrame, not just some Numpy arrays out in the wild. Here’s how I’d handle this if we wanted to plot every column against the index.

df = pd.DataFrame(data)           # our dataframe
line_colors = {
'column1':'green',
'column2':'red',
'column3':'blue'
}
for column in df.columns:
fig.add_trace(go.Scatter(
x=df.index,
y=df[column],
name=column,
line_color=line_colors[column]
)
)

Here I define line colors for each different column, give each one an appropriate name in the legend using the name parameter when instantiating theScatter object, and only have to write out a short for-loop to accomplish it all.

4. Update the figure layout

fig.update_layout(title='Sample Graph',
xaxis_title='x',
yaxis_title='y',
template='plotly_white')

This is where we define all of the labels like our title, axes titles, legend options, etc. template sets the background color, text font, etc. and can be customized as you’d like. You can do many many things here. Check out the documentation for more ideas!

Closing remarks

A great way to learn Plotly is to understand the framework used here and explore this documentation. Because this library is relatively new, it’s difficult to find answers to very specific problems on sites like StackOverflow.

Let me know in the comments if you have any preferred conventions for plotly graphs. I’d love to keep improving my own workflow.

--

--