ScreenIT Collabs

09/9/2019

By: Admin

Plotly Fundamentals

It is 2019. Don’t we deserve something better than Matplotlip to build our graphs? Sure we do! Enter Plotly, an awesome and super versatile library to create a wide array of compelling data visualizations.

In this article, I want to introduce you to the version 4 of Plotly. While this library is very extense, I want to give you the fundamentals that will have you up and running. If you want to follow the examples, I recommend you use a Jupyter notebook.

By the way, the Plotly documentation is supberp!

What is plotly?

Plotly is two things: a company and a group of open source graphing libraries. plotly.js is a JavaScript library built on top of D3. We can use it in Python thanks to plotly.py, a Python library that manipulates the JavaScript version.

The bad old days

Previous to version 4, we had 4 possible functions to create the plots:

  • plotly.plotly.plot()
  • plotly.plotly.iplot()
  • plotly.offline.plot()
  • plotly.offline.iplot()

 

Now, things are much easier; we have a single function: plotly.io.show. There is another way to create your graphs, the show() method of the Figure object; but we’ll get back to that later.

Basics. The Figure structure and plotting dictionaries

At the center of a graph lays the Figure structure. We can see it as the specification of what data we want to plot and how we want to plot it. We can represent a Figure simply as a Python dictionary.

A Figure must contains two sub-structures: Data, which simply is a list of Trace specifications, and Layout.

Each Trace is an specification of how we want a particular set of data plotted. This is the structure where we specify the coordinates of the points we want to plot. As with Figure, we can represent a Trace with a Python Dictionary. Depending on the type of graph, the attributes for the Trace object will vary; nevertheless, there are some common properties; for instance, “type” specifies what kind of plot we want to build (the default is “scatter”).

This is the general layout of a Figure structure:

  • Figure: an structure that contains Data and Layout
    • Data: a list of Trace.
      • Trace: a collection of property-value pairs.
    • Layout: a collection of property-value pairs. This specification indicates the look and feel of the Figure in general. 

If you want to know all the available properties for these structures, you can check out the full reference

But, how do we plot a Figure-dictionary? It is quite simple, we’d use the plotly.io.show function we mentioned before.

In [1]:

import plotly.io as pio

fig = {

    “data”: [{“type”: “scatter”,

              “x”: [1, 2, 3.5],

              “y”: [2.5, 4, 2]}],

    “layout”: {“title”: {“text”: “A Scatter Plot”}}

}

pio.show(fig)

Graph objects to represent the figures

While it is completely valid to use dictionaries to specify our graphs, Plotly offers a group of specialized objects to create and tune each aspect of our plots; collectively, they are called graph objects. In order to access them, we need to import the right package:

import plotly.graph_objects as go

The Figure object

To build a Figure object, we can specify the data and layout parameters; this is very logic if we remember the specification the Figure specification.

Now, something very convenient from the Figure object is its show method, which we can call to immediately display our graph. Let us see a quick example:

In [2]:

import plotly.graph_objects as go

fig = go.Figure(

    data=[{“type”:”bar”, “x”:list(“ABC”), “y”:[1, 3, 2]}],

    layout={

        “title”:{“text”:”A Bar Chart”}

    }

)

fig.show()

Data

There is not a data object on its own; rather, we represent the Data specification a a list of Trace objects.

The Trace object.

Unlike the trace structure created with dictionaries, we do not set the type property directly; instead, we use one of the specialized subclasses of the Trace object. For instance, if we want to create a scatter plot, we’d use the object plotly.graph_objects.Scatter; similarly, if we wanted to build a bar plot, the plotly.graph_objects.Bar object would be the appropriate.

Most Trace objects share some common parameters as:

  • name. It helps us identify and refer to each Trace object in the graph
  • x. A list that represent each point coordinate in the x-axis.
  • y. A list that represent each point coordinate in the y-axis.

In the same sense, each type of trace object possesses its own set of parameters, depending on the nature of the plot.

Let us see how we’d use the Trace objects:

In [3]:

import plotly.graph_objects as go

trace1 = go.Scatter(name=”first_line”, x=[1, 2, 3], y=[-1, 0, 2])

trace2 = go.Scatter(name=”second_line”, x=[-1, 0, 2], y=[1, 2, 3])

go.Figure(data=[trace1, trace2])

The Layout object

We can find this object as plotly.graph_objects.Layout It determines how the plot is gonna look like. In this object we can adjust aspects as legends, axes, colors, grids, etc.

Let us see an example:

In [4]:

import plotly.graph_objects as go

 

trace1 = go.Scatter(x=[1,2,3], y=[4, 0, -5])

trace2 = go.Scatter(x=[7,6,1], y=[4, 5, -5])

layout_obj = go.Layout(showlegend=True, legend={“x”: 0.5, “y”:0.5}, 

                       xaxis={“showgrid”:True, “gridcolor”:”orange”, 

                              “title”:”X axis”})

fig = go.Figure(data=[trace1, trace2], layout=layout_obj)

fig.show()

Magic underscore notation

Given that the graph objects can have deeply nested properties, it can quickly become tedious to modify one of these properties. Do not worry, though! Plotly is got your back covered with magic underscore notation. For instance, we can go from this:

import plotly.graph_objects as go

fig = go.Figure(

    data=[go.Scatter(y=[1, 3, 2], line=dict(color=“crimson”))],

    layout=dict(title=dict(text=“A Chart”))

)

to this

fig = go.Figure(

    data=[go.Scatter(y=[1, 3, 2], line_color=“crimson”)],

    layout_title_text=“A Chart”

)

The underscores often mean that some nested property is being accessed; however, there are some properties that include an underscore in its name. These cases don’t imply magic underscore notation.

Updating Figures

No matter if a Figure is specified with dictionaries or with graph-objects, it can be later updated.

Adding traces

In this case, we’d use the method go.Figure.add_trace in order to add new traces.

import plotly.graph_objects as go

 

fig = go.Figure()

fig.add_trace(go.Bar(x=[1, 2, 3], y=[1, 3, 2]))

fig.show()

By the way, there is also a family of add-methods to add specific traces. The advantage of this approach is that we can define the trace as we are adding it. As an example, let us suppose we want to add a new scatter trace to our graph:

import plotly.graph_objects as go

 

fig = go.Figure()

fig.add_scatter(y=[4, 2, 1], mode=“lines”, row=1, col=1)

fig.show()

Updating traces

update_traces method

We can update the properties of the Trace objects; for that, we’d use the go.Figure.update_traces(patch=None, selector=None, **kwargs) method. Let us explore its main parameters:

  • patch is a dictionary with the properties we want for the selected traces. It is also valid to indicate a property directly as part of the kwargs.
  • selector is a dictionary. All trace object that match the key-value pairs indicated in the dictionary will be the active traces that the method will affect. If no dictionary is indicated, the update_traces method will affect all the traces present.

The magic underscore notation is valid for both, patch and selector.

As usual, en example may come in handy:

In [5]:

import plotly.graph_objects as go

 

fig = go.Figure()

fig.add_scatter(y=[2, 3.5, 4], mode=”markers”,

                marker=dict(size=20, color=”MediumPurple”),

                name=”c”)

fig.add_bar(y=[1, 3, 2],

            marker=dict(color=”LightSeaGreen”),

            name=”d”)

fig.update_traces(marker_color=”yellow”, marker_size=75,

                  selector=dict(marker_color=”MediumPurple”))

fig.show()

for each trace method

We can traverse the collection of Trace objects with the method go.Figure.for_each_trace(fn, selector=None, **kwargs)

  • fn is a functions that takes a trace object and updates it.
  • selector is a dictionary. All trace object that match the key-value pairs indicated in the dictionary will be the active Traces that the method will affect.

Update layout method

Maybe our data is just fine but we want to tweak the look of our graph; no problem! with method go.Figure.update_layout, we can update all the properties of the Layout object.

We can indicate the properties-value pairs for the layout in two ways, using a dictionary, or directly indicating the attributes as keyword arguments int the function. In either case, magic-underscore notation is valid.

import plotly.graph_objects as go

 

fig = go.Figure(data=go.Bar(x=[1, 2, 3], y=[1, 3, 2]))

fig.update_layout(title_text=“A Bar Chart”, title_font_size=30,

                  title_font_color=“cyan”)

fig.show()

 

About the Author

Karlo is a Chemist who fell in love with Statistics. He’s been working as a coder in Mexico’s Health Department for the last 8 years. He’s a believer of the power of computing to free people from boring and repetitive tasks, giving them more time to be creative. Collaboration, sharing, and teamwork are fundamental traits of his work creed.