DEV Community

Daisy Auma
Daisy Auma

Posted on

# Build an Interactive Sales Chart with Plotly

Static sales charts in Excel or spreadsheets do not let you explore your data dynamically. Want to zoom in on a specific month? Compare different products? You need to create new charts manually. In this tutorial, you will build an interactive sales chart in Python using Plotly that lets users hover for details, zoom into timeframes, and filter by product.

Prerequisites

Before we begin, make sure you have:

Python 3.7 or higher installed on your system. You will need two libraries: Plotly for creating interactive visualizations and Pandas for handling data. Install them using pip:

pip install plotly pandas
Enter fullscreen mode Exit fullscreen mode

You can run this code in any Python environment: VS Code, Jupyter Notebook, PyCharm, or even the command line. The interactive charts will open in your default browser.

This tutorial assumes you are comfortable with basic Python syntax and have used Pandas DataFrames before. You should know how to load data and access columns. You do not need any prior experience with Plotly. We will be using Plotly Express, the high-level interface that makes creating charts simple and intuitive.

The Data

We will work with a year's worth of monthly sales data for three products: Laptops, Tablets, and Smartphones. The dataset contains revenue figures (in dollars) for each product across all 12 months of 2024.

I have hosted the data on GitHub (https://raw.githubusercontent.com/Daisy-Faith-Auma/plotly-sales-tutorial/refs/heads/main/sales_data.csv) for easy access. Let us load it:

import pandas as pd
import plotly.express as px

# Load the sales data
df = pd.read_csv('https://raw.githubusercontent.com/Daisy-Faith-Auma/plotly-sales-tutorial/refs/heads/main/sales_data.csv')

# Convert Month column to datetime for proper time-series plotting
df['Month'] = pd.to_datetime(df['Month'])

# Take a look at the data
print(df.head())
Enter fullscreen mode Exit fullscreen mode

You should see a DataFrame with three columns: Month, Product, and Revenue. The data shows interesting patterns: Laptops have steady growth, Tablets show some seasonal variation, and Smartphones spike during the holiday season.

Step 1: Basic Line Chart

Let us create our first chart. Plotly Express makes this remarkably simple:

# Create a basic line chart
fig = px.line(df, x='Month', y='Revenue', title='Monthly Sales Revenue')
fig.show()
Enter fullscreen mode Exit fullscreen mode

Create a basic line chart

When you run this, a browser window opens showing your visualization. Try hovering over the line. You will see data points appear. You can also zoom by clicking and dragging, and pan by holding shift while dragging.

But there is a problem: this chart combines all three products into a single line, which is not useful for comparison. We are summing up all the revenue without distinguishing between Laptops, Tablets, and Smartphones.

Notice what Plotly provides: automatic axis labels, a title, grid lines, and basic interactivity.

Step 2: Add Hover Interactivity

Now let us separate our products and make the hover information more useful. We will tell Plotly to create a different line for each product:

# Create separate lines for each product
fig = px.line(df, 
              x='Month', 
              y='Revenue', 
              color='Product',
              title='Monthly Sales Revenue by Product')

fig.show()
Enter fullscreen mode Exit fullscreen mode

Create separate lines for each product

Now you have three distinct lines, each in a different color. The legend appears automatically, and you can click on product names to show or hide specific lines.

Let us improve the hover tooltips to show properly formatted currency:

# Customize hover information
fig = px.line(df, 
              x='Month', 
              y='Revenue', 
              color='Product',
              title='Monthly Sales Revenue by Product',
              labels={'Revenue': 'Revenue ($)', 'Month': 'Month'})

# Format the hover template
fig.update_traces(hovertemplate='<b>%{fullData.name}</b><br>' +
                                'Month: %{x|%B %Y}<br>' +
                                'Revenue: $%{y:,.0f}<br>' +
                                '<extra></extra>')

fig.show()
Enter fullscreen mode Exit fullscreen mode

Customize hover information

Now when you hover, you see formatted information: the product name in bold, the full month name with year, and revenue formatted as currency with comma separators. The <extra></extra> removes the redundant trace name that appears by default.

Try hovering over different points. The formatting makes the data much more readable and professional.

Step 3: Multiple Products with Legend

Our chart already shows multiple products, but let us polish it further. We will improve the layout and make the legend more functional:

# Enhanced multi-product chart
fig = px.line(df, 
              x='Month', 
              y='Revenue', 
              color='Product',
              title='2024 Sales Performance Dashboard',
              labels={'Revenue': 'Revenue ($)', 'Month': 'Month'})

# Customize hover information
fig.update_traces(hovertemplate='<b>%{fullData.name}</b><br>' +
                                'Month: %{x|%B %Y}<br>' +
                                'Revenue: $%{y:,.0f}<br>' +
                                '<extra></extra>')

# Improve layout
fig.update_layout(
    hovermode='x unified',  # Show all products when hovering over a month
    legend=dict(
        title='Product Line',
        orientation='h',
        yanchor='bottom',
        y=1.02,
        xanchor='right',
        x=1
    )
)

fig.show()
Enter fullscreen mode Exit fullscreen mode

Enhanced multi-product chart

Two key improvements here:

First, hovermode='x unified' shows data for all products simultaneously when you hover over a specific month. This makes comparisons easier. You can instantly see which product performed best in any given month.

Second, we have repositioned the legend horizontally above the chart. This saves vertical space and keeps all product information visible while you explore the data. Try clicking on legend items. You can show or hide products to focus on specific comparisons.

Step 4: Dropdown Product Selector

For the final enhancement, let's add a dropdown menu that lets users filter by product. This is particularly useful when presenting to stakeholders who want to focus on specific product lines:

# Create the base figure
fig = px.line(df, 
              x='Month', 
              y='Revenue', 
              color='Product',
              title='2024 Sales Performance Dashboard',
              labels={'Revenue': 'Revenue ($)', 'Month': 'Month'})

# Customize hover
fig.update_traces(hovertemplate='<b>%{fullData.name}</b><br>' +
                                'Month: %{x|%B %Y}<br>' +
                                'Revenue: $%{y:,.0f}<br>' +
                                '<extra></extra>')

# Add dropdown menu
fig.update_layout(
    updatemenus=[
        dict(
            buttons=list([
                dict(label="All Products",
                     method="update",
                     args=[{"visible": [True, True, True]}]),
                dict(label="Laptop",
                     method="update",
                     args=[{"visible": [True, False, False]}]),
                dict(label="Tablet",
                     method="update",
                     args=[{"visible": [False, True, False]}]),
                dict(label="Smartphone",
                     method="update",
                     args=[{"visible": [False, False, True]}])
            ]),
            direction="down",
            showactive=True,
            x=0.5,
            xanchor='center',
            y=1.15
        )
    ]
)

fig.show()
Enter fullscreen mode Exit fullscreen mode

Add dropdown menu

Add dropdown menu

The dropdown menu appears at the top of your chart. Users can select "All Products" to see everything, or choose individual products for focused analysis. This transforms your chart into an interactive dashboard that serves multiple purposes.

Wrap-up

You have now built an interactive sales dashboard with hover tooltips showing formatted data, synchronized hovering across products, and a dropdown filter. These features make data exploration intuitive and engaging.

You can save your chart as a standalone HTML file with fig.write_html('sales_dashboard.html') for easy sharing. The HTML file can be opened in any browser without requiring Python or any additional software.

Try experimenting with your own sales data by replacing the CSV URL, or explore other chart types like bar charts and scatter plots using the same Plotly Express patterns you have learned here.

Top comments (0)