Line charts visualize data trends over an axis, with line colors highlighting patterns in the data. Plotly enables detailed customization of line colors in different ways. In this comprehensive guide, we‘ll explore Plotly‘s flexible options for setting line chart colors with code examples.
We‘ll be looking at data on monthly website visitors over 2 years.
import pandas as pd
import numpy as np
np.random.seed(1)
df = pd.DataFrame({
"Month": pd.date_range(start="2020-01-01", periods=24, freq="MS"),
"Visitors": np.random.randint(15000, 25000, 24)
})
Overview
There are several main approaches for customizing line colors in Plotly:
- Plotly Express: Quick high-level coloring with
line_colorandcolor_discrete_sequence - Graph Objects: Fine-grained control through trace properties like
line.color - Color Mapping: Map colors to aspects like trace names and data values
- Colorscales: Sample sequential, diverging and categorical palettes
- Dash Callbacks: Dynamic interactivity by setting colors in callbacks
We‘ll provide code samples for each method using the website visitor data.
Plotly Express
Plotly Express builds charts using sensible defaults. We can override colors easily through arguments like line_color.
line_color for Single Lines
Use the line_color attribute to set a single color for the line.
import plotly.express as px
fig = px.line(df, x=‘Month‘, y=‘Visitors‘, line_color=‘darkorange‘)
fig.show()

This overrides the default blue line with a nice dark orange color.
color_discrete_sequence for Multiple Lines
For charts with multiple lines, use color_discrete_sequence to specify a color palette.
import numpy as np
df2 = df.copy()
df2[‘Visitors2‘] = np.random.randint(10000, 20000, 24)
fig = px.line(df2, x=‘Month‘, y=[‘Visitors‘, ‘Visitors2‘],
color_discrete_sequence=[‘red‘, ‘blue‘])
fig.show()

The order of colors maps to the order of the y column names.
Graph Objects and Mapping
For more flexibility, Plotly Graph Objects allow setting detailed attributes for each trace.
Trace Line Colors
Pass colors through a dictionary to the line.color property.
import plotly.graph_objects as go
fig = go.Figure(data=[
go.Scatter(
x=df[‘Month‘],
y=df[‘Visitors‘],
line=dict(color=‘green‘)
)
])
fig.show()

This overrides the default black lines with a green color for this trace.
Mapping Colors
Colors can also be mapped to aspects like trace names.
colors = {‘visitors‘: ‘blue‘, ‘visitors2‘: ‘red‘}
fig = go.Figure(data=[
go.Scatter(
name=‘visitors‘,
x=df[‘Month‘],
y=df[‘Visitors‘],
),
go.Scatter(
name=‘visitors2‘,
x=df[‘Month‘],
y=df2[‘Visitors2‘]
)
])
fig.update_traces(line=dict(color=colors))
fig.show()

The traces are colored based on the name-color mapping.
Categorical Colorscales
Import Plotly colorscale constants to sample from different sequential and diverging color palettes.
For example, the Viridis scale provides visually uniform colors:
from plotly.colors import sequential
fig.update_traces(line=dict(color=sequential.Viridis))
Plotly offers various categorical colorscales like these.
Multicategory colorscales are also available. This can be useful for coloring based on an attribute like browser:
colors = [‘rgb(239,243,255)‘, ‘rgb(189,215,231)‘, ‘rgb(107,174,214)‘]
fig.update_traces(
line=dict(color=df[‘browser_category‘]),
marker=dict(
color=df[‘browser_category‘],
colorscale=colors
)
)
Best Practices for Line Color Choices
Choosing accessible colors ensures that information encoded in the line colors is conveyed accurately:
Perceptual Uniformity
Picking perceptually uniform colors allows easier comparison between lines. Viridis and other sequential scales achieve this well.
Color Vision Deficiency Friendly
Lines should be distinguishable by people with common types of color blindness. Online palette pickers can identify problem color combinations.
Avoid Rainbow Colorscales
Rainbow scales should typically be avoided despite their popularity. Adjacent colors are rarely ordered intuitively.
Interactivity with Line Colors
Line colors can also be tied to interactive chart features in Plotly.
Hover Colors
This shows the currently hovered line in a darker shade compared to others:
import plotly.express as px
fig = px.line(df2, x=‘Month‘, y=[‘Visitors‘, ‘Visitors2‘])
fig.update_traces(hovertemplate=None, hoverinfo="skip") # disable tooltip
fig.update_traces(line=dict(width=4)) # thicken lines
def darken_color(color):
return f‘rgb({max(0,int(color[i:i+2])-30)},{max(0,int(color[i+2:i+4])-30)},{max(0,int(color[i+4:i+6])-30)})‘
fig.update_traces(
line=dict(color=[f‘rgb(100, 10, 200)‘, f‘rgb(10, 100, 200)‘]),
hoverline=dict(
color=[darken_color(f‘rgb(100, 10, 200)‘),
darken_color(f‘rgb(10, 100, 200)‘)]
)
)
fig.show()

Here the hovered line transitions to a darker color.
Linked Brushing
Linking interactive selections across charts is enabled through lines with mapped colors:
import plotly.express as px
fig = px.line(df, x=‘Month‘, y=‘Visitors‘)
fig2 = px.line(df2, x=‘Month‘, y=‘Visitors2‘)
fig.update_traces(line=dict(color=‘blue‘))
fig2.update_traces(line=dict(color=‘red‘))
fig.data[0].update(
selectedpoints=fig2.data[0].selectedpoints
)
fig2.data[0].update(
selectedpoints=fig.data[0].selectedpoints
)
fig.show()
fig2.show()
Selecting points on one chart will highlight linked points on the other chart.
Dynamic Colors in Dash Callbacks
For interactive Dash apps, line colors can be set dynamically in callbacks responding to user input.
Here is an app allowing choosing between predefined colorscales:
import dash
from dash import dcc, html
import plotly.express as px
from dash.dependencies import Input, Output
from plotly.colors import sequential, diverging, cyclical
colorscales = {
‘Viridis‘: sequential.Viridis,
‘Cividis‘: sequential.Cividis,
‘Turbo‘: sequential.Turbo,
‘Rainbow‘: diverging.Picnic,
‘Sinebow‘: cyclical.IceFire
}
app = dash.Dash()
app.layout = html.Div([
dcc.Dropdown(id=‘colorscale-dropdown‘, clearable=False, value=‘Viridis‘,
options=[{‘label‘: cs, ‘value‘: cs}
for cs in colorscales]),
dcc.Graph(id=‘colorscale-graph‘),
])
@app.callback(
Output(‘colorscale-graph‘, ‘figure‘),
[Input(‘colorscale-dropdown‘, ‘value‘)])
def update_graph(colorscale):
fig = px.line(df, x=‘Month‘, y=‘Visitors‘)
fig.update_traces(
line={‘color‘: colorscales[colorscale]}
)
return fig
app.run_server()
This allows dynamically swapping the line color palette through user selection.

Exporting and Color Support
When exporting figures to static files, some additional steps may be needed to retain custom colors depending on the file type.
Static Image Formats
Exported PNG images support transparency and custom colors by default.
For JPEG and WebP formats which don‘t support transparency, make sure to set an opaque background color rather than fully transparent:
fig.update_layout(plot_bgcolor=‘white‘)
fig.write_image("figure.jpg")
PDF Export
PDF exports require explicitly setting RGB color values rather than names.
So a color like ‘red‘ needs to be converted to ‘rgb(255, 0, 0)‘ for inclusion in PDF exports.
Comparisons to Matplotlib and Seaborn
Plotly offers more flexibility in customization over Matplotlib and Seaborn. Some differences in approach:
- Plotly links colors to traces rather than referring to plots
- More built-in color palettes andquickstart options
- Interactivity and real-time color updating in Dash apps
- Generally more customization features for web viz
But Matplotlib is useful for simple charting and publication-quality static images.
Seaborn provides convenience functions for statistical charting with nice default styles and palettes.
Additional Examples and Patterns
Here are some more advanced examples building on Plotly‘s color functionality.
Data-Driven Continuous Colors
Color values can be set dynamically based on data values for continuous color mapping:
fig = px.line(df, x=‘Month‘, y=‘Visitors‘)
fig.update_traces(
line={‘color‘: df[‘Visitors‘]},
marker={‘color‘: df[‘Visitors‘]}
)

This scales visitors from low (blue) to high (red).
A colorscale is used under the hood to map data ranges to colors.
Categorical Colors by Groups
Trace lines can be colored according to categorical variables like groups.
Here visitors are split into 4 line traces by traffic source:
df[‘source‘] = np.random.choice([‘organic‘, ‘ad‘, ‘direct‘, ‘referral‘],
size=len(df))
fig = px.line(df, x=‘Month‘, y=‘Visitors‘, color=‘source‘)
fig.update_layout(legend=dict(
yanchor="bottom",
y=-0.2,
xanchor="left",
x=0
))
fig.show()

The color legend can also be customized.
Cyclical Colormaps
Cyclical colorscales that loop from low to high to low can encode line time series with seasonal cycles:
from plotly.colors import cyclical
fig = px.line(df2, x=‘Month‘, y=‘Visitors‘)
fig.update_traces(
line={‘color‘: cyclical.Phase},
marker={‘color‘: cyclical.Phase}
)
fig.show()

The color cycles with time conveying the cyclical nature.
Conclusion
In this guide, we explored how to leverage Plotly‘s versatile options for customizing line colors, including Plotly Express parameters, trace properties, color mapping, categorical colorscales, and dynamic interactivity with Dash.
Choosing appropriate colors and palettes effectively highlights patterns in line chart data for accurate communication of information. By offering flexible built-in tools for tailored visualization, Plotly enables concise and customizable line color specification.
To learn more, refer to Plotly‘s official documentation on controlling chart colors.


