An Intro to Customizing Charts in Plotly Express

Raven Welch
Analytics Vidhya
Published in
6 min readJul 22, 2020

Plotly Express is probably my new favorite data viz tool in python, especially after learning how to take control of it to make it look even nicer. Here, I’ll walk you through the basics to help you on your way to mastering making pretty charts with Plotly Express.

Before we start, we have to have some data to play with! For this, I used this video game sales data from Kaggle. I dropped all null values just for this article, but do keep in mind that you should generally avoid doing that in practice!

import pandas as pd#Importing the initial dataframe
df1 = pd.read_csv("data/vgsales.csv").dropna()
df1.Year = df1.Year.astype("int")
#First Modified Dataframe
df2 = df1.groupby("Genre").sum().drop(columns = ["Year", "Rank"]).sort_values(by = "Global_Sales").reset_index()
#Second modified Dataframe
top_genres = ["Platform", "Role-Playing", "Shooter", "Sports", "Action"]
df3 = df1[df1.Genre.isin(top_genres)].groupby(["Genre", "Year"]).sum().drop(columns="Rank").reset_index()

Great! Now, on to the fun part. If you haven’t already installed the package, there are instructions on how to install the current version here. If you have it, great! All you need to run is import plotly.express as px and you can follow along!

We’ll be using a (dreaded) pie chart, a bar graph, and a line chart throughout this article. The code for each are as follows:

#Percentage of how many games are in each category
px.pie(df1, names = "Genre")
#Total lifetime global profit per genre
px.bar(df2, x = "Genre", y = "Global_Sales")
#Global profit over time for top 5 genres
px.line(df3, "Year", "Global_Sales"

Now… as you can see here these are all quite bland or even impossible to read. Plus, there aren’t even any titles and the axis names are just the variables used! Fortunately, both issues are quite easy to fix!

First, let’s add a title to the pie chart, and go ahead and switch to a different color pallet since the default feels a bit harsher on the eyes. We just need to add a title and pick a color_discrete_sequence ! Discreet colors in Plotly are used for categorical data.

fig1 = px.pie(df1, names = "Genre", title = "Distribution of Video Game Genres", color_discrete_sequence=px.colors.qualitative.Set3)fig1.show()

Next, let’s make the global sales chart nicer. For this, I actually want to flip the graph so the bars are horizontal, and for that all i need to do is reverse the x and y variables, and add orientation = 'h' !

The title is set the same as the previous pie chart, however the labels aren’t as initially obvious! labels takes a dict object, with each key corresponding to the name of the column used for x and y! On top of that, we’re going to be using a continuous color scale corresponding to Global_Sales , and for this i chose "darkmint"

fig2 = px.bar(df2, y = "Genre", x = "Global_Sales", title = "Total Global Sales per Video Game Genre",
labels = {"Global_Sales": "Global Sales in Millions (USD)", "Genre": "Video Game Genre"},
orientation = 'h',color = "Global_Sales", color_continuous_scale = "darkmint")
fig2.show()

Not perfect, but certainly a lot easier to read! Plus, who doesn’t love a horizontal bar chart? Certainly not me!

Now, are you keeping up? Yes? Fantastic! Then we shall be moving on to our final chart!

For this one, I’ve decided I don’t want to use any of the built in color pallets, so I’m setting it to completely different colors. For that, I’ll be using color_discrete_sequence and I’ll be passing it a list of color values! You can use named CSS colors, hex, HSV/HSVA, HSL/HSLA, and RGB/RGBA color formats! (The ‘A’ stands for Alpha, which is used to declare the transparency of the color, 0 for completely transparent and 100 for completely solid)

Additionally, I’ve decided to set template to one of Plotly’s built in themes. Since we all know dark themes are the best themes, I’ve set it to plotly_dark

Don’t forget to set the title and labels attributes! This time, I’m leaving Genre and Year alone, since I don’t want to make it too wordy.

line_colors = ["#7CEA9C", '#50B2C0', "rgb(114, 78, 145)", "hsv(348, 66%, 90%)", "hsl(45, 93%, 58%)"]fig3 = px.line(df3, "Year", "Global_Sales", height = 500, width = 800, color = "Genre", 
title = "Global Profit for Top Video Game Genres Over Time",
labels = {"Global_Sales": "Global Sales in Millions (USD)"},
template = "plotly_dark",
color_discrete_sequence=line_colors)
fig3.show()

What about customizing the theme yourself? Well, you can modify things like the title, background colors, and so much more! For now, let’s just use the plotly_dark theme as our main template and just make a few minor modifications to it. Using fig.update_layout() we can pass along dictionaries to it to easily modify or add different features.

A cool and new modified chart!

Using the title attribute, we can set pass it a dictionary with {'x': 5} to center it! Next, we can set the font attribute to {'family': 'courier'} , one of my favorite web-save fonts. For the background color, we can just pass along plot_bgcolor = "#232624" , no dictionaries needed!

line_colors = ["#7CEA9C", '#50B2C0', "rgb(114, 78, 145)", "hsv(348, 66%, 90%)", "hsl(45, 93%, 58%)"]fig3 = px.line(df3, "Year", "Global_Sales", height = 500, width = 800, color = "Genre", 
title = "Global Profit for Top Video Game Genres Over Time",
labels = {"Global_Sales": "Global Sales in Millions (USD)"},
template = "plotly_dark",
color_discrete_sequence=line_colors)
fig3.update_layout(plot_bgcolor = "#23262F",
title = {'x':0.5},
font = {"family" : "courier"})
fig3.show()

Wonderful! Though, if you haven’t noticed already, the hover box is looking a bit… lackluster, and doesn’t fit in with our theme! Don’t worry, that’s quite an easy fix!

The default Plotly Express hover box

With update.traces() , we can use customdata and hovertemplate to make it look nice and neat!

For customdata, we’ll need to import NumPy and pass along an ndarray object. In that, we’ll add each column from the dataframe with extra data that we want to use. For this, we’ll add the sales information for specified sale locations.

import numpy as npfig3.update_traces(
customdata = np.stack((df3.NA_Sales, df3.EU_Sales, df3.JP_Sales, df3.Other_Sales), axis = -1))

Next, we’ll start filling in the information for hovertemplate. It takes a string, and some formatting can be used using d3-format’s syntax and some minor HTML, and you can use variables using this %{variable} format. We can pass along values like x and y from our graph, as well as values from customdata !

We’ll make the top line bold using <b> , make all location words italicized using <i> , add line breaks using <br> , and then insert data using the handy %{variable} markup , first referring to x (year) and y (global sales). For global sales, I’m using d3-format syntax to add a $ before the number, and using .2f to limit the variables to only 2 decimal points. All in all, a piece of cake, albeit a bit hard on the eyes.

And as a final, fun bonus: Let’s make the font size a bit bigger and change the font itself to Courier to match the rest of the chart using hoverlabel !

fig3.update_traces(
customdata = np.stack((df3.NA_Sales, df3.EU_Sales, df3.JP_Sales, df3.Other_Sales), axis = -1),
hovertemplate = """
<b>Total Sales during %{x}:<br></b>
%{y:$.2f}M <i>Global</i><br>
%{customdata[0]:$.2f}M <i>North America</i><br>
%{customdata[1]:$.2f}M <i>European</i><br>
%{customdata[2]:$.2f}M <i>Japan</i><br>
%{customdata[3]:$.2f}M <i>Other</i><br>""",

hoverlabel = {"font_size" : 14, "font_family" : "Courier"}
)
fig3.show()
Our final hover box! Fantastic!

Welcome to the end of the article, you’ve made it! Now that you’re here, I’ll pass along some helpful resources!

The Plotly documentation is, of course, a given, but there’s a lot of other handy resources out here! And as always, remember to google!

--

--

Analytics Vidhya
Analytics Vidhya

Published in Analytics Vidhya

Analytics Vidhya is a community of Generative AI and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com