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_color and color_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.

Similar Posts