Area Charts with Plotly Express
By: Darío Weitz
Tags: Data Visualization, Data Science, Plotly, Charts And Graphs, Storytelling

Area Charts with Plotly Express

Image by Pawel Czerwinski from Unsplash

Plotly Graph Objects

Plotly Express, an object-oriented interface to figure creation, was released in 2019. It is a high-level wrapper for Plotly.py that includes functions to plot standard 2D & 3D charts and choropleth maps. Fully compatible with the rest of the Plotly ecosystem, is an excellent tool for the rapid development of exploratory charts.

But if you want to enhance your plots, you need to import a group of classes named graph objects.

import plotly.graph_objects as go fig = go.Figure()

The plotly.graph_objects module contains a hierarchy of Python classes. Figure is a primary class. Figure has a data attribute and a layout attribute. The data attribute has more than 40 objects, each one refers to a specific type of chart (trace) with its corresponding parameters. The layout attribute specifies the properties of the figure as a whole (axes, title, shapes, legends, etc.).

The conceptual idea is to use fig.add_trace() and fig.update_layout() to manipulate these attributes in order to enhance already constructed figures.

Let’s analyze this methodology with different types of area charts.

Area Charts

An area chart is a form of line chart with the area between the horizontal axis and the line that connects data points filled with color. They are used to communicate an overall trend without being concerned about showing exact values.

The vertical axis represents a quantitative variable while the horizontal axis is a timeline or a sequence of numerical intervals. Data points are connected by line segments forming a polyline, and the area between the polyline and the horizontal axis is filled with color or some type of shading.

There are four types of area charts (AC): 1) Standard AC; 2) Stacked AC; 3) Percent Stacked AC; 4) Overlapping AC.

1. — Standard Area Chart (AKA Area Graph): they are particularly effective to show the evolution of a numerical variable over time. The idea is to put more emphasis on the overall trend and on the peaks and troughs of the line that connects the data points.

2. — Stacked Area Chart: it’s like several area charts stacked on top of one another. In this type of chart, there is a third variable, usually categorical, with its corresponding data series. Each data series representation begins where the previous data series ends (they do not overlap). The final figure indicates the sum of all the data represented.

3. — Percent Stacked Area Chart (AKA 100% Stacked Area Chart): just like the previous chart, several areas are stacked on top of one another and a third categorical variable is represented. It is a Part-to-whole chart where each area indicates the percentage of each part referred to the total of the category. The final height of the vertical axis is always 100%. This means that there is a second baseline on the top of the chart that helps to track some particular trends.

4. — Overlapping Area Charts: in this kind of graph there is some overlapping between areas. Colors and transparency must be properly adjusted so particular lines can be easily seen. They allow us to make very good comparisons between trends.

Area Charts with Plotly Express

We worked with a dataset downloaded from Kaggle [1]. The dataset contains records related to Video Games Sales & Game Ratings Data Scraped from VzCharts. We particularly selected a csv file with 1031 records about Video Games sales on the Playstation 4 platform by Sony. We would like to know how sales were distributed in different regions of the world in the period 2013–2018.

First, we imported Plotly Express as px, the Pandas library as pd and converted our csv file into a dataframe:

import pandas as pd

import plotly.express as px path ='your path'

df = pd.read_csv(path + 'PS4_GamesSales2.csv',

index_col = False, header = 0, sep = ';', engine='python')

The screenshot below shows the first ten records of the dataset:

Remember: real-world data is dirty. So we did some cleaning before using the data. Particularly, we used dropna to eliminate rows with N/A values in the Year column, and used drop to delete rows with 0 values in the Global column. Then we split the data into groups based on the Year column and applied the function sum() on each group.

df.dropna(subset = ['Year'], inplace = True) df.drop(df[df['Global'] == 0.0].index, inplace = True) df_area = df.groupby(['Year']).sum().reset_index()

Now we are ready to draw our first chart.

For the standard area chart in this article, the Plotly Express function is px.area and the corresponding parameters are: data_frame; x= a name of a column in data_frame representing the timeline; y= a name of a column in data_frame representing the statistic calculated. We updated the chart with update.layout: set the title, the size of the font, and set the figure dimensions with width and height. Then we updated the x-axis and the y-axis (text, font, tickfont). We saved the chart as a static png file and finally, we drew the chart using the default template (plotly, “Histograms with Plotly Express, Themes & Templates”, https://towardsdatascience.com/histograms-with-plotly-express-e9e134ae37ad).

fig1 = px.area(

df_area, x = 'Year', y = 'Global') fig1.update_layout(

title = "PS4 Global Sales",

title_font_size = 40,

width = 1600, height = 1400) fig1.update_xaxes(

title_text = 'Year',

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig1.update_yaxes(

title_text = "Sales (MM)",

range = (0,160),

title_font=dict(size=30,family='Verdana',color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig1.write_image(path + "figarea1.png")

fig1.show()

Fig. 1: Standard Area Chart. Graph made by the author with Plotly Express.

The graph above indicates the evolution in the number of PS4 global sales for the period 2013–2018. The same story could have been told with a line graph but without the visual power of the area chart.

But remember that we would like to know how sales were distributed in different regions of the world during the same period. So we need a stacked area chart where each area (each region) contributes to the total (the whole, sum of sales). The height of each area represents the value of each particular region whilst the final height is the sum of those values.

Now we used the module plotly.graph_objects with a different methodology [fig.add_trace()] and a different trace [go.Scatter()]. x= is the name of a column in data_frame representing the timeline while y= is the name of a column in data_frame representing a particular region. The stackgroup parameter is used to add the y values of the different traces in the same group. We must include mode = ‘lines’ to draw lines instead of points.

import plotly.graph_objects as go

fig2 = go.Figure() fig2.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['North America'],

name = 'North America',

mode = 'lines',

line=dict(width=0.5, color='orange'),

stackgroup = 'one')) fig2.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Europe'],

name = 'Europe',

mode = 'lines',

line=dict(width=0.5,color='lightgreen'),

stackgroup = 'one')) fig2.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Japan'],

name = 'Japan',

mode = 'lines',

line=dict(width=0.5, color='blue'),

stackgroup = 'one')) fig2.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Rest of World'],

name = 'Rest of World',

mode = 'lines',

line=dict(width=0.5, color='darkred'),

stackgroup = 'one')) fig2.update_layout(

title = "PS4 Global Sales per Region",

title_font_size = 40, legend_font_size = 20,

width = 1600, height = 1400) fig2.update_xaxes(

title_text = 'Year',

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig2.update_yaxes(

title_text = "Sales (MM)", range = (0,160),

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig2.write_image(path + "figarea2.png")

fig2.show()

Fig. 2: Stacked Area Chart. Graph made by the author with Plotly Express.

Let’s see if a percent stacked area chart improves the storytelling. We only need to make one small change: add groupnorm = ‘percent’ to the first add_trace().

fig3 = go.Figure() fig3.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['North America'],

name = 'North America',

mode = 'lines',

line=dict(width=0.5, color='orange'),

stackgroup = 'one',

groupnorm = 'percent')) fig3.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Europe'],

name = 'Europe',

mode = 'lines',

line=dict(width=0.5,color='lightgreen'),

stackgroup = 'one')) fig3.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Japan'],

name = 'Japan',

mode = 'lines',

line=dict(width=0.5, color='blue'),

stackgroup = 'one')) fig3.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Rest of World'],

name = 'Rest of World',

mode = 'lines',

line=dict(width=0.5, color='darkred'),

stackgroup = 'one')) fig3.update_layout(

title = "PS4 Global Sales per Region",

title_font_size = 40, legend_font_size = 20,

yaxis=dict(type='linear',ticksuffix='%'),

width = 1600, height = 1400) fig3.update_xaxes(

title_text = 'Year',

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig3.update_yaxes(

title_text = "Sales (%)", range = (0,100),

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig3.write_image(path + "figarea3.png")

fig3.show()

Fig. 3: Percent Stacked Area Chart. Graph made by the author with Plotly Express.

Figure 3 is a Part-to-whole chart where each area indicates the percentage of each region referred to the total of the world sales. The emphasis is on the trend, how the percentage of each category changes over time, and not on the exact values.

Finally, we can compare the regions with the highest sales using an overlapping area chart. Instead of stackgroup, we add fill = ‘tozeroy’ to the first add_trace() and fill = ‘tonexty’ to the second add_trace().

fig4 = go.Figure() fig4.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['North America'],

name = 'North America',

mode = 'lines', line=dict(width=0.5,color='lightgreen'),

fill = 'tozeroy')) fig4.add_trace(go.Scatter(

x= df_area['Year'], y = df_area['Europe'],

name = 'Europe',

mode = 'lines', line=dict(width=0.5, color='darkred'),

fill = 'tonexty')) fig4.update_layout(

title = "PS4 Sales North America vs Europe",

title_font_size=40, legend_font_size = 20,

width = 1600, height = 1400) fig4.update_xaxes(

title_text = 'Year',

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig4.update_yaxes(

title_text = "Sales (MM)", range = (0,70),

title_font=dict(size=30, family='Verdana', color='black'),

tickfont=dict(family='Calibri', color='darkred', size=25)) fig4.write_image(path + "figarea4.png")

fig4.show()

Fig. 4: Overlapping Area Chart. Graph made by the author with Plotly Express.

To sum up:

We use Area Charts to communicate the overall trend and the relative contribution of each part to the whole without being concerned about showing exact values.

We use the plotly.graph_objects module to add traces sequentially by means of the add_trace method. Then we manipulate the chart attributes through update_layout, update_xaxes, and update_yaxes.

If you find this article of interest, please read my previous (https://medium.com/@dar.wtz):

“Scatter Plots with Plotly Express, Trendlines & Faceting”

“Histograms with Plotly Express, Themes & Templates”

References

[1]: https://www.kaggle.com/sidtwr/videogames-sales-dataset?select=PS4_GamesSales.csv