Styling Plotly Express Figures in Python
Figures made with Plotly Express can be customized in all the same ways as figures made with graph objects, as well as with PX-specific function arguments.
New to Plotly?
Plotly is a free and open-source graphing library for Python. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.
Styling Figures made with Plotly Express¶
Plotly Express is the easy-to-use, high-level interface to Plotly, which operates on a variety of types of data. Every Plotly Express function returns a plotly.graph_objects.Figure
object whose data
and layout
has been pre-populated according to the provided arguments.
You can style and customize figures made with Plotly Express in all the same ways as you can style figures made more manually by explicitly assembling
graph_objects
into a figure.
More specifically, here are the 4 ways you can style and customize figures made with Plotly Express:
- Control common parameters like width & height, titles, labeling and colors using built-in Plotly Express function arguments
- Updating the figure attributes using update methods or by directly setting attributes
- Using Plotly's theming/templating mechanism via the
template
argument to every Plotly Express function - Setting default values for common parameters using
px.defaults
Built-in Plotly Express Styling Arguments¶
Many common styling options can be set directly in the px
function call. Every Plotly Express function accepts the following arguments:
title
to set the figure titlewidth
andheight
to set the figure dimensionstemplate
to set many styling parameters at once (see below for more details)labels
to override the default axis and legend labels behaviour, which is to use the data frame column name if available, and otherwise to use the label name itself like "x", "y", "color" etc.labels
accepts adict
whose keys are the label to rename and whose values are the desired labels. These labels appear in axis labels, legend and color bar titles, and in hover labels.category_orders
to override the default category ordering behaviour, which is to use the order in which the data appears in the input.category_orders
accepts adict
whose keys are the column name to reorder and whose values are alist
of values in the desired order. These orderings apply everywhere categories appear: in legends, on axes, in bar stacks, in the order of facets, in the order of animation frames etc.hover_data
andhover_name
to control which attributes appear in the hover label and how they are formatted.- Various color-related attributes such as
color_continuous_scale
,color_range
,color_discrete_sequence
and/orcolor_discrete_map
set the colors used in the figure.color_discrete_map
accepts a dict whose keys are values mapped tocolor
and whose values are the desired CSS colors.
To illustrate each of these, here is a simple, default figure made with Plotly Express. Note the default orderings for the x-axis categories and the usage of lowercase & snake_case data frame columns for axis labelling.
import plotly.express as px
df = px.data.tips()
fig = px.histogram(df, x="day", y="total_bill", color="sex")
fig.show()
Here is the same figure, restyled by adding some extra parameters to the initial Plotly Express call:
import plotly.express as px
df = px.data.tips()
fig = px.histogram(df, x="day", y="total_bill", color="sex",
title="Receipts by Payer Gender and Day of Week",
width=600, height=400,
labels={ # replaces default labels by column name
"sex": "Payer Gender", "day": "Day of Week", "total_bill": "Receipts"
},
category_orders={ # replaces default order by column name
"day": ["Thur", "Fri", "Sat", "Sun"], "sex": ["Male", "Female"]
},
color_discrete_map={ # replaces default color mapping by value
"Male": "RebeccaPurple", "Female": "MediumPurple"
},
template="simple_white"
)
fig.show()
Updating or Modifying Figures made with Plotly Express¶
If none of the built-in Plotly Express arguments allow you to customize the figure the way you need to, you can use the update_*
and add_*
methods on the plotly.graph_objects.Figure
object returned by the PX function to make any further modifications to the figure. This approach is the one used throughout the Plotly.py documentation to customize axes, control legends and colorbars, add shapes and annotations etc.
Here is the same figure as above, with some additional customizations to the axes and legend via .update_yaxes()
, and .update_layout()
, as well as some annotations added via .add_shape()
and .add_annotation()
.
import plotly.express as px
df = px.data.tips()
fig = px.histogram(df, x="day", y="total_bill", color="sex",
title="Receipts by Payer Gender and Day of Week vs Target",
width=600, height=400,
labels={"sex": "Payer Gender", "day": "Day of Week", "total_bill": "Receipts"},
category_orders={"day": ["Thur", "Fri", "Sat", "Sun"], "sex": ["Male", "Female"]},
color_discrete_map={"Male": "RebeccaPurple", "Female": "MediumPurple"},
template="simple_white"
)
fig.update_yaxes( # the y-axis is in dollars
tickprefix="$", showgrid=True
)
fig.update_layout( # customize font and legend orientation & position
font_family="Rockwell",
legend=dict(
title=None, orientation="h", y=1, yanchor="bottom", x=0.5, xanchor="center"
)
)
fig.add_shape( # add a horizontal "target" line
type="line", line_color="salmon", line_width=3, opacity=1, line_dash="dot",
x0=0, x1=1, xref="paper", y0=950, y1=950, yref="y"
)
fig.add_annotation( # add a text callout with arrow
text="below target!", x="Fri", y=400, arrowhead=1, showarrow=True
)
fig.show()
How Plotly Express Works with Templates¶
Plotly has a theming system based on templates and figures created with Plotly Express interact smoothly with this system:
- Plotly Express methods will use the default template if one is set in
plotly.io
(by default, this is set toplotly
) or inplotly.express.defaults
(see below) - The template in use can always be overridden via the
template
argument to every PX function - The default
color_continuous_scale
will be the value oflayout.colorscales.sequential
in the template in use, unless it is overridden via the corresponding function argument or viaplotly.express.defaults
(see below) - The default
color_discrete_sequence
will be the value oflayout.colorway
in the template in use, unless it is overridden via the corresponding function argument or viaplotly.express.defaults
(see below)
By way of example, in the following figure, simply setting the template
argument will automatically change the default continuous color scale, even though we have not specified color_continuous_scale
directly.
import plotly.express as px
df = px.data.iris()
fig = px.density_heatmap(df, x="sepal_width", y="sepal_length", template="seaborn")
fig.show()
Setting Plotly Express Styling Defaults¶
Plotly Express supports a simple default-configuration system via the plotly.express.defaults
singleton object. The values of the properties set on this object are used for the rest of the active session in place of None
as the default values for any argument to a PX function with a matching name:
width
andheight
can be set once globally for all Plotly Express functionstemplate
can override the setting ofplotly.io.templates.default
for all Plotly Express functionscolor_continuous_scale
andcolor_discrete_scale
can override the contents of the template in use for all Plotly Express functions that accept these argumentsline_dash_sequence
,symbol_sequence
andsize_max
can be set once globally for all Plotly Express functions that accept these arguments
To illustrate this "defaults hierarchy", in the following example:
- we set the Plotly-wide default template to
simple_white
, but - we override the default template for Plotly Express to be
ggplot2
, but - we also set the default
color_continuous_scale
, and - we set the default
height
andwidth
to 400 by 600, but - we override the default
width
to 400 via the function argument.
As a result, any figure produced with Plotly Express thereafter uses the ggplot2
settings for all attributes except for the continuous color scale (visible because simple_white
doesn't set a plot background, and neither the simple_white
nor ggplot2
template uses Blackbody
as a color scale), and uses the Plotly Express defaults for height but not width (visible because the figure height is the same as the figure width, despite the default).
import plotly.express as px
import plotly.io as pio
pio.templates.default = "simple_white"
px.defaults.template = "ggplot2"
px.defaults.color_continuous_scale = px.colors.sequential.Blackbody
px.defaults.width = 600
px.defaults.height = 400
df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="sepal_length", width=400)
fig.show()
What About Dash?¶
Dash is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.
Learn about how to install Dash at https://dash.plot.ly/installation.
Everywhere in this page that you see fig.show()
, you can display the same figure in a Dash application by passing it to the figure
argument of the Graph
component from the built-in dash_core_components
package like this:
import plotly.graph_objects as go # or plotly.express as px
fig = go.Figure() # or any Plotly Express function e.g. px.bar(...)
# fig.add_trace( ... )
# fig.update_layout( ... )
from dash import Dash, dcc, html
app = Dash()
app.layout = html.Div([
dcc.Graph(figure=fig)
])
app.run_server(debug=True, use_reloader=False) # Turn off reloader if inside Jupyter