Featured resource
Tech Upskilling Playbook 2025
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Learn more
  • Labs icon Lab
  • Data
Labs

Build a Line Chart in Python to Visualize Stock Price Trends

In this Lab, Build a Line Chart in Python to Visualize Stock Price Trends, you'll create stock trend visualizations using Python's two leading charting libraries. You'll begin by constructing basic line charts using Matplotlib, then progress into interactive and highly customizable plots using Plotly Express and Plotly Graph Objects. Along the way, you’ll implement key visualization features like hover interactions, date formatting, annotations, secondary axes, and even animated time-series views. By the end, you'll know how to transform raw financial data into compelling, analytics-ready visuals.

Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 2h 12m
Last updated
Clock icon Aug 21, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Getting Started

    Getting Started

    Welcome to this interactive Code Lab, where you’ll learn how to visualize stock price trends using line charts in Python with Matplotlib and Plotly.

    You’ll begin by creating a basic line plot to display stock closing prices over time. As you progress, you’ll enhance your visualizations with labels, styling, interactivity, and advanced features like annotations, secondary axes, and animations. By the end of the lab, you’ll have a collection of clear, professional charts ready for analysis and presentation.

    Each step introduces a specific concept and walks you through its implementation in a Jupyter Notebook environment.

    Open the Notebook

    From the workspace panel, open the notebook file: 1-step-one.ipynb.

    How to Complete Tasks

    Each task in the lab matches a pre-written code cell labeled Task 1.1, Task 1.2, and so on.

    To complete a task:

    • Locate the corresponding code cell in the notebook.
    • Follow the # TODO comments provided in the cell.
    • Fill in any blanks as indicated.
    • Run the cell using the Run button or press Shift + Enter.
    • Save your work using the Save icon or File > Save and Checkpoint.
    • Validate your solution by clicking Validate in the task block.

    You do not need to open a terminal, create additional files, or use plt.savefig(). All code runs and renders inline in the notebook.


    info> Important: You must save your notebook (Ctrl/Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

  2. Challenge

    Step 1: Plot a Basic Line with Matplotlib

    Step 1: Create a Basic Line Plot

    To start, you’ll create your first line chart to visualize stock closing prices over time. This simple plot establishes the foundation for all the enhancements you’ll add in later steps.

    Line charts are commonly used in finance to display price movement, track trends, and highlight key time periods.

    In this step, you’ll generate a clear, readable line chart using only the essential Matplotlib functions.


    What You’ll Learn in This Step

    • Create a basic line chart with plt.plot()
    • Use a label to identify the data series
    • Display the legend using plt.legend()
    • Render the chart inside your notebook with plt.show()

    Open the Notebook

    From the workspace panel, open the notebook file: 1-step-one.ipynb.

    info> Important: You must save your notebook (Ctrl/Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    How to Complete Each Task
    • Find the matching code cell labeled Task 1.1.
    • Fill in the blanks and follow the # TODO comments in the cell.
    • Run the cell using the Run button or by pressing Shift+Enter.
    • Save your progress using the Save icon or File > Save and Checkpoint.
    • All code and output will appear inline in the notebook.
    ### Creating a Basic Line Chart with Matplotlib

    Matplotlib provides the plot() function to create simple line charts. A line chart connects a sequence of data points with straight lines, making it easier to see how values change over time.

    The plot() function requires at least two arguments:

    • x: The data for the horizontal axis, such as dates.
    • y: The data for the vertical axis, such as numeric values.

    You can also include a label argument to describe the line for clarity. Labels help identify the data series in your visualization, especially when comparing multiple lines.

    In most workflows, you first create a figure, then plot the data and apply additional customization such as labels, titles, and styles.

  3. Challenge

    Step 2: Add Labels and Styling in Matplotlib

    Step 2: Add Labels and Style the Chart

    A chart becomes truly informative when viewers can immediately grasp its context and read values with ease. In this step, you’ll enhance your Matplotlib line chart with:

    • A concise title that explains what the chart shows
    • Axis labels so readers understand the time and price dimensions
    • Gridlines that make it simple to trace values across dates
    • A larger figure size and well-formatted date ticks for long timelines

    These adjustments turn a raw plot into a polished visual suitable for presentations and reports.


    What You Will Learn

    • Add a chart title using plt.title()
    • Label the x- and y-axes with plt.xlabel() and plt.ylabel()
    • Enable gridlines with plt.grid()
    • Adjust figure geometry through figsize
    • Format date ticks using matplotlib.dates.DateFormatter

    Open the Notebook

    From the workspace panel, open the notebook file: 2-step-two.ipynb.

    info> Important: Save your notebook (Ctrl / Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    Task Workflow
    • Locate the code cell whose header matches each task (for example, Task 2.1).
    • Follow the # TODO comments and replace every placeholder (_____) with working code.
    • Run the cell using the Run button or Shift + Enter.
    • Save your progress before validation. All output appears inline; no external files are required.
    ### Add Titles, Labels, and Gridlines

    Charts communicate effectively when you add clear titles and labels to explain the context of the data.
    Matplotlib provides simple functions to include this context and improve readability.


    Titles
    • plt.title("Title Text") adds a descriptive heading above the chart area.

    Axis Labels
    • plt.xlabel("Label Text") names the horizontal axis.
    • plt.ylabel("Label Text") names the vertical axis.

    Axis labels help viewers understand what each dimension represents.


    Gridlines
    • plt.grid(True) draws horizontal and vertical reference lines behind the data.
    • Grids make it easier to estimate values and compare positions.

    Rotating Tick Labels
    • plt.xticks(rotation=angle) rotates labels on the x-axis to improve spacing and legibility.
    • In many cases, labels are angled at 45 or 90 degrees to prevent overlapping text.

    Format Dates and Adjust Figure Size

    Charts that span months or years need extra room and smart tick labels.
    Three Matplotlib components handle that job:

    Figure Size
    • Use plt.figure(figsize=(width, height)) to set the size of your chart in inches.
    • A wider figure helps keep date labels from overlapping.

    MonthLocator
    • mdates.MonthLocator(interval=n) generates major tick positions at fixed month intervals.

      • interval=1 → one tick every month
      • interval=3 → one tick every quarter
      • interval=12 → one tick every year

    DateFormatter
    • mdates.DateFormatter(fmt) controls how dates are displayed.

      • %b → abbreviated month (Jan, Feb)
      • %Y → four-digit year (2025)
      • %d → day of month

    For example, "%b %Y" shows dates as Jan 2025.


    Applying the Locator and Formatter

    To apply your locator and formatter, you first get the current axis using:

    plt.gca()
    

    gca() stands for get current axes, it returns the axes object of your current plot.

    Then, you set the tick behavior:

    plt.gca().xaxis.set_major_locator(locator)
    plt.gca().xaxis.set_major_formatter(formatter)
    
    • set_major_locator() tells Matplotlib where to put the ticks.
    • set_major_formatter() defines how each tick label should look.
  4. Challenge

    Step 3: Transition to Plotly Express

    Step 3: Transition to Plotly Express

    Matplotlib gives you static images; Plotly Express adds interactivity with almost no extra code. In this step you will recreate the line chart from Step 2 using plotly.express.line(), gaining hover tooltips, zooming, and a polished theme by default.

    Plotly Express is the high-level wrapper around Plotly Graph Objects. You specify the DataFrame, choose which columns map to each visual channel, and Express handles the rest—legend, axes, and responsive layout included.


    What You Will Learn

    • Construct an interactive line chart with px.line()
    • Add a title and axis labels directly through function parameters
    • Separate multiple series with the color and line_group arguments
    • Apply a built-in theme using the template parameter
    • Format x-axis date ticks for readability

    Open the Notebook

    From the workspace panel, open the notebook file: 3-step-three.ipynb.

    info> Important: Save your notebook (Ctrl / Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    Task Workflow
    • Locate the code cell whose header matches each task (for example, Task 3.1).
    • Follow the # TODO comments and add working code.
    • Run the cell using the Run button or Shift + Enter.
    • Save your progress before validation. All output appears inline; no external files are required.
    ### Creating an Interactive Line Chart

    Plotly Express simplifies the process of building interactive line charts that respond to user actions like zooming and hovering.
    The px.line() function generates a figure directly from a structured dataset.


    Core Parameters
    • data_frame defines the dataset containing the chart data.
    • x specifies the column for the horizontal axis.
    • y specifies the column for the vertical axis.
    • title sets a descriptive heading for the chart.
    • labels provides a dictionary that maps column names to custom display names for the axes and tooltips.

    Plotly Express charts include built-in features such as interactive tooltips, panning, and export options. ### Using Color and Grouping

    When working with datasets that include multiple categories or series, color and grouping help distinguish them visually. Plotly Express provides arguments that assign visual attributes to specific columns.


    Where These Arguments Are Used

    These arguments are specified directly inside the px.line() function when you create the figure.
    For example:

    fig = px.line(
        dataframe,
        x="dateColumn",
        y="valueColumn",
        color="categoryColumn",
        line_group="categoryColumn",
        template="plotly_dark"
    )
    

    This approach combines all configuration in a single function call that returns the interactive chart object.


    Color
    • color sets the color of each line based on the values in a chosen column.
    • This creates a unique color for each category.

    Example:

    color="columnName"
    

    Line Group
    • line_group groups data points into separate lines so multiple series can appear together.
    • Each unique value in the column creates a distinct line.

    Example:

    line_group="columnName"
    

    Template
    • template applies a pre-built visual theme to the chart.
    • Templates control background, font, and default colors.

    Example:

    template="plotly_dark"
    

    Available Built-In Templates
    • plotly
    • plotly_white
    • plotly_dark
    • ggplot2
    • seaborn
    • simple_white
    • none
    ### Adding Detailed Tooltips with hover_data

    Plotly Express allows customization of hover tooltips so charts can display additional information when users move their cursor over data points.
    The hover_data parameter accepts a dictionary that controls which columns appear in the tooltip and how their values are formatted.


    Basic Usage
    • The dictionary keys are column names from the dataset.
    • The dictionary values define the numeric format using d3 formatting codes.

    Example:

    hover_data={
        "columnA": ":.2f",
        "columnB": ":,.0f"
    }
    

    Formatting Codes
    • :.2f displays two decimal places (e.g., 1234.50).
    • :,.0f displays whole numbers with commas (e.g., 1,000).
    • :.1% shows percentages with one decimal place (e.g., 54.3%).

    Columns that are not included in the dictionary are hidden by default. Any column can also be excluded explicitly by assigning False as the value.


    Common Formatting Examples
    • .0f shows an integer with commas (1,000)
    • .1f shows one decimal place (1000.0)
    • .2f shows two decimal places (1000.00)
    • .3f shows three decimal places (1000.000)
    • $,.2f shows currency formatting ($1,000.00)
    • % shows as percentage (0.5 becomes 50%)
    • .1% shows percentage with one decimal (0.543 becomes 54.3%)

    Note: The hover_data dictionary is passed as a parameter inside the px.line() function. ### Formatting Date Ticks

    When working with time series data, formatting the tick labels on the x-axis improves clarity and readability.
    Plotly charts include a method called update_xaxes() that modifies the display format of dates.


    tickformat

    The tickformat argument accepts formatting codes that control how dates appear.

    Common codes include:

    • %b: Abbreviated month name (Jan, Feb)
    • %Y: Four-digit year (2025)
    • %d: Day of the month (01, 15)

    Combining these codes creates consistent date labels.

    Example:

    tickformat="%b %Y"
    

    This example displays dates as Jan 2025.


    Applying tickformat to a Figure

    To set the date format, call update_xaxes() on the figure object:

    Example:

    fig.update_xaxes(tickformat="formatString")
    
  5. Challenge

    Step 4: Enhance Plotly Line Chart Appearance

    Step 4: Enhance Plotly Line Chart Appearance

    After creating basic interactive charts, the next step is to customize their appearance and make them easier to interpret. Plotly Express offers flexible options to style lines, markers, and axis formatting.

    In this step, you’ll apply advanced styling to your line charts to improve clarity and visual appeal. You’ll also learn how to control time series display, legend order, and line shapes.


    What You’ll Learn in This Step

    • Add markers to emphasize individual data points
    • Smooth lines using line_shape="spline"
    • Control the legend order with category_orders
    • Use update_traces() to style line color, width, and dash pattern
    • Format the x-axis date display and adjust ranges

    Open the Notebook

    From the workspace panel, open the notebook file: 4-step-four.ipynb.

    info> Important: You must save your notebook (Ctrl/Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    How to Complete Each Task
    • Find the matching code cell labeled Task 4.1, Task 4.2, etc.
    • Fill in the blanks and follow the # TODO comments in each cell.
    • Run the cell using the Run button or by pressing Shift+Enter.
    • Save your progress using the Save icon or File > Save and Checkpoint.
    • All code and output will appear inline in the notebook.
    ### Adding Markers and Smoothing Lines

    Combining markers and smoothed curves in time series charts helps reveal trends while maintaining visibility of individual data points.
    Plotly Express provides arguments to control marker display, line shape, legend ordering, and rendering mode.


    Markers
    • markers controls whether each point along the line is shown as a marker.
    • Setting markers=True enables visible markers.

    Example:

    markers=True
    

    Smoothed Lines
    • The line_shape argument defines how lines connect data points.
    • Using "spline" creates a smooth curve.

    Example:

    line_shape="spline"
    

    Category Ordering
    • The category_orders argument defines the order of categories in the legend and axis.
    • A dynamic example:
    category_orders = {"columnName": sorted(dataframe["columnName"].unique())}
    

    Render Mode
    • The render_mode argument specifies how the chart is drawn.
    • Setting render_mode="svg" is required when using line_shape="spline".

    Example:

    render_mode="svg"
    

    Applying Custom Line Styles

    Plotly Express charts can be further customized after creation by using the update_traces() method on the figure object.
    This method allows detailed control over the appearance of lines and markers.


    Line Color
    • The color property sets the line color.
    • Colors can be specified by name or hex code.

    Example:

    line=dict(color="blue")
    

    Line Width
    • The width property controls the thickness of the line.

    Example:

    line=dict(width=3)
    

    Line Dash Style
    • The dash property defines the pattern of the line.

    • Common options include:

      • "solid"
      • "dot"
      • "dash"
      • "longdash"
      • "dashdot"

    Example:

    line=dict(dash="dash")
    

    Applying Updates

    The update_traces() method applies the style to all traces in the figure unless filtered.

    Example:

    fig.update_traces(line=dict(color="blue", width=3, dash="dash"))
    

    Plotting Multiple Lines by Category

    When working with time series data for multiple categories, showing all series in the same chart makes comparisons easier.
    Plotly Express can automatically create separate lines based on the values in a column.


    Color
    • The color argument assigns a unique color to each line based on a categorical column.
    • Each category is automatically added to the legend.

    Example:

    color="columnName"
    

    Line Group
    • The line_group argument helps Plotly Express connect data points into lines.
    • This is useful if the dataset contains repeated combinations of categories and dates.

    Example:

    line_group="columnName"
    

    Combined Usage

    Using both color and line_group ensures each series is clearly separated and consistently colored in the chart. ### Formatting X-Axis Date Labels

    When time series charts span long periods, default date labels can overlap or become hard to read.
    Plotly Express provides the update_xaxes() method to control date formatting and tick display.


    tickformat

    The tickformat argument specifies how dates are shown.

    Common formatting codes include:

    • %b: Abbreviated month name (Jan, Feb)
    • %Y: Four-digit year (2025)
    • %d: Day of the month (01, 15)

    Example:

    tickformat="%b %Y"
    

    This displays dates as Jan 2025.


    Rotating Labels

    You can also rotate the labels by setting tickangle.

    Example:

    tickangle=45
    

    Applying the Settings

    The update_xaxes() method accepts one or more arguments to customize the x-axis:

    Example:

    fig.update_xaxes(tickformat="formatString", tickangle=angle)
    

    This allows the chart to remain legible and organized even when displaying many dates.

  6. Challenge

    Step 5: Use Graph Objects for Fine Control

    Step 5: Use Plotly Graph Objects for Fine Control

    Plotly Express makes it easy to create quick charts, but sometimes you need more customization than Express can provide. Plotly Graph Objects offer a lower-level API for constructing figures manually with complete control over every detail.

    In this step, you’ll recreate similar line charts using Graph Objects to understand how traces, layouts, and figure objects interact. You’ll also explore how to build charts incrementally and customize specific elements like annotations and axes.


    What You’ll Learn in This Step

    • Create line charts using go.Figure() and go.Scatter()
    • Combine multiple traces in a single figure
    • Customize layout properties, titles, and axis settings
    • Add annotations and reference lines
    • Update figure properties after creation

    Open the Notebook

    From the workspace panel, open the notebook file: 5-step-five.ipynb.

    info> Important: You must save your notebook (Ctrl/Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    How to Complete Each Task
    • Find the matching code cell labeled Task 5.1, Task 5.2, etc.
    • Fill in the blanks and follow the # TODO comments in each cell.
    • Run the cell using the Run button or by pressing Shift+Enter.
    • Save your progress using the Save icon or File > Save and Checkpoint.
    • All code and output will appear inline in the notebook.
    ### Creating a Basic Line Chart with Graph Objects

    Plotly Graph Objects provide a lower-level API for creating charts by manually defining figure components.
    Instead of using px.line(), you create a figure with go.Figure() and then add one or more traces such as go.Scatter().


    go.Figure
    • go.Figure() creates an empty figure object that can contain traces and layout properties.

    Example:

    figure = go.Figure()
    

    go.Scatter
    • go.Scatter() defines the data and appearance for a single line series.
    • You pass x and y data along with optional styling arguments.

    Example:

    trace = go.Scatter(
        x=dataframe["dateColumn"],
        y=dataframe["valueColumn"],
        mode="lines"
    )
    

    Adding Traces
    • Use add_trace() to attach the trace to the figure.

    Example:

    figure.add_trace(trace)
    

    This approach allows full control over each trace and makes it possible to combine multiple series in the same figure. ### Adding Multiple Traces

    When visualizing time series data for different categories, adding separate traces to the same figure makes comparisons easier.
    In Graph Objects, each trace is created manually. Unlike Plotly Express, Graph Objects do not automatically split data into groups based on a column.


    Why Looping and Filtering Are Needed

    Plotly Express can create multiple lines automatically by specifying color="columnName".
    With Graph Objects, you build each trace yourself. To create one line per category, you need to:

    • Identify all unique values in the category column.
    • Filter the dataset to include only the rows for each value.
    • Create a trace for that subset.
    • Add it to the figure.

    Selecting Unique Categories

    You can get all unique category values with:

    Example:

    dataframe["categoryColumn"].unique()
    

    This returns a list of all unique labels.


    Filtering Rows for One Category

    You can create a smaller DataFrame (a subset) by filtering:

    Example:

    subset = dataframe[dataframe["categoryColumn"] == "Category A"]
    

    This keeps only the rows where the column equals "Category A".


    Creating and Adding Traces

    Each trace is defined using go.Scatter().

    Example:

    trace = go.Scatter(
        x=subset["dateColumn"],
        y=subset["valueColumn"],
        mode="lines",
        name="Category A"
    )
    

    Looping Over Categories to Build All Traces

    You can loop through all unique categories to create and add each trace:

    Example:

    for value in dataframe["categoryColumn"].unique():
        subset = dataframe[dataframe["categoryColumn"] == value]
        trace = go.Scatter(
            x=subset["dateColumn"],
            y=subset["valueColumn"],
            mode="lines",
            name=value
        )
        figure.add_trace(trace)
    ``` ### Customizing Layout Properties
    
    Graph Objects separate data (traces) from the layout, which controls titles, axes, and other visual settings.
    </br>
    The `update_layout()` method applies changes to the figure’s layout.
    
    </br>
    
    ##### Title
    
    * The `title` argument sets the main chart heading.
    
    Example:
    ```python
    update_layout(title="Chart Title")
    

    Axis Labels
    • The xaxis_title argument labels the horizontal axis.
    • The yaxis_title argument labels the vertical axis.

    Example:

    update_layout(
        xaxis_title="X Axis Label",
        yaxis_title="Y Axis Label"
    )
    

    Grid and Background
    • Additional options like background color and grid style can also be configured in the layout.

    Example:

    update_layout(
        plot_bgcolor="white",
        xaxis=dict(showgrid=True),
        yaxis=dict(showgrid=True)
    )
    

    Adding Annotations

    Annotations highlight important points or events in a chart by adding text labels and optional arrows.
    Graph Objects support annotations through the layout.annotations property.


    Defining an Annotation

    An annotation is defined as a dictionary specifying the text, position, and style.

    Example:

    annotation = dict(
        x="2025-01-01",
        y=100,
        text="Event Label",
        showarrow=True,
        arrowhead=1
    )
    

    Adding Annotations

    Annotations are added using update_layout() with the annotations argument.

    Example:

    update_layout(annotations=[annotation])
    

    Multiple Annotations

    You can pass a list of multiple annotation dictionaries to display several labels on the same figure.

  7. Challenge

    Step 6: Add Annotations and Shapes in Plotly

    Step 6: Add Annotations and Shapes in Plotly

    Charts become more informative when you add annotations and visual markers to highlight important events. Plotly Graph Objects provide powerful methods to draw shapes, highlight ranges, and label specific data points.

    In this step, you’ll learn how to create custom shapes like vertical lines and shaded regions, and explore different ways to position annotations relative to data or the overall chart layout.


    What You’ll Learn in This Step

    • Use add_shape() to add lines and shaded regions
    • Mark key dates or ranges visually
    • Add annotations linked to specific data points
    • Position annotations relative to the data (xref="x") or the chart area (xref="paper")

    Open the Notebook

    From the workspace panel, open the notebook file: 6-step-six.ipynb.

    info> Important: You must save your notebook (Ctrl/Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    How to Complete Each Task
    • Find the matching code cell labeled Task 6.1, Task 6.2, etc.
    • Fill in the blanks and follow the # TODO comments in each cell.
    • Run the cell using the Run button or by pressing Shift+Enter.
    • Save your progress using the Save icon or File > Save and Checkpoint.
    • All code and output will appear inline in the notebook.
    ### Adding Shapes to Highlight Key Dates and Ranges

    Shapes can be added to a chart to mark important dates or highlight specific time periods.
    Graph Objects provide the add_shape() method to draw lines, rectangles, and other shapes on the figure.


    Adding a Vertical Line

    A vertical line can be used to mark a specific date. This is done by creating a line shape with the same x-coordinate for both ends.

    Example:

    add_shape(
        type="line",
        x0="2025-01-01",
        x1="2025-01-01",
        y0=0,
        y1=1,
        xref="x",
        yref="paper",
        line=dict(color="red", width=2, dash="dash")
    )
    

    In this example:

    • xref="x" means the x-position uses data coordinates.
    • yref="paper" means the line spans the full height of the chart (0 to 1).

    Adding a Shaded Region

    A rectangle shape can be used to highlight a date range.

    Example:

    add_shape(
        type="rect",
        x0="2025-01-01",
        x1="2025-03-01",
        y0=0,
        y1=1,
        xref="x",
        yref="paper",
        fillcolor="LightSalmon",
        opacity=0.3,
        line_width=0
    )
    

    This creates a transparent shaded box covering the selected range. ### Adding Annotations Anchored to Data Coordinates

    Annotations are text labels that point to important values or events in your chart.
    When you want an annotation to stay attached to a specific data point, you can anchor it to data coordinates using xref="x" and yref="y".


    Defining an Annotation

    Annotations are defined as dictionaries with properties that control text, position, and style.

    Example:

    annotation = dict(
        x="2023-06-01",
        y=150,
        text="Market Surge",
        showarrow=True,
        arrowhead=2,
        ax=0,
        ay=-40,
        xref="x",
        yref="y"
    )
    

    Anchoring to Data
    • xref="x" means the x-position uses data coordinates.
    • yref="y" means the y-position uses data coordinates.
    • This keeps the annotation attached to the data point even if you zoom or pan.

    Adding the Annotation

    Annotations are added using update_layout() with the annotations argument:

    Example:

    update_layout(annotations=[annotation])
    

    This approach makes it easy to highlight peaks, dips, or any other specific event. ### Adding Layout-Relative Annotations

    Annotations can also be positioned relative to the entire chart area instead of data coordinates.
    This is helpful for adding general labels, notes, or instructions that should stay in a fixed place regardless of zoom or panning.


    Layout Coordinates
    • xref="paper" anchors the x-position relative to the chart area (0 to 1).
    • yref="paper" anchors the y-position relative to the chart area (0 to 1).
    • For example, x=0.5 and y=0.9 will place the annotation near the top center.

    Defining a Layout Annotation

    Example:

    annotation = dict(
        x=0.5,
        y=0.9,
        text="Overall Chart Annotation",
        showarrow=False,
        font=dict(size=14, color="black"),
        xref="paper",
        yref="paper"
    )
    

    Adding the Annotation

    Layout annotations are added the same way using update_layout():

    Example:

    update_layout(annotations=[annotation])
    
  8. Challenge

    Step 7: Create Animated and Faceted Charts

    Step 7: Create Animated and Faceted Charts

    Plotly makes it possible to build dynamic, interactive charts that reveal trends over time or show multiple groups in separate panels. In this step, you’ll learn how to create custom animations, facet charts, and advanced subplots to explore your data in new ways.

    You’ll build an animated line chart that progressively grows over time, create faceted charts to compare multiple series side by side, and combine traces into subplots for more flexible layouts.


    What You’ll Learn in This Step

    • Create custom animations with go.Figure and frames to show cumulative trends
    • Use facet_row and facet_col to build faceted panels in Plotly Express
    • Combine multiple traces into subplots with make_subplots() and configure axis synchronization

    Open the Notebook

    From the workspace panel, open the notebook file: 7-step-seven.ipynb.

    info> Important: You must save your notebook (Ctrl/Cmd + S) before clicking Validate. Validation checks the most recent saved checkpoint.

    How to Complete Each Task
    • Find the matching code cell labeled Task 7.1, Task 7.2, etc.
    • Follow the # TODO comments and write your code step by step.
    • Run the cell using the Run button or press Shift + Enter.
    • Save your work using the Save icon or File > Save and Checkpoint.
    • All code and output will appear inline in the notebook.
    ### Creating a Growing Line Animation with Play and Timeline Controls

    This type of animation builds a line that grows point by point across time, rather than replacing the entire trace in each frame.
    It shows a cumulative trend that makes it easier to understand how a series evolves step by step.

    You can play, pause, or scrub through the timeline to see how the data develops.


    Key Concepts

    Filtering Data for One Category and Year

    Before you build the animation, you often need to filter your DataFrame to focus on a specific category (like a stock ticker) and a specific year.

    To do this:

    • Create variables to store your selections.
    • Use boolean conditions to filter rows.
    • Sort the results by date so the animation flows in order.
    • Reset the index to get clean row numbering.

    Example (generic column names):

    category = "CategoryName"
    year = 2022
    
    filteredData = df[
        (df["CategoryColumn"] == category) &
        (df["DateColumn"].dt.year == year)
    ].sort_values("DateColumn").reset_index(drop=True)
    

    This produces a DataFrame with rows for your chosen category and year, sorted chronologically.


    Frames Frames are snapshots of your figure at different stages. In a growing animation, each frame includes all data up to a specific index so the line lengthens over time.

    How Frames Work

    Each frame contains the trace data up to a given point.

    Example (using generic column names):

    go.Frame(
        data=[
            go.Scatter(
                x=filteredData.loc[:i, "columnX"],
                y=filteredData.loc[:i, "columnY"],
                mode="lines+markers"
            )
        ],
        name=str(i)
    )
    

    This approach ensures the line grows forward as each frame is displayed.


    Updatemenus The updatemenus property adds playback controls to the figure. This is how you create Play and Pause buttons so the animation can be started or stopped manually.

    About Play and Pause Buttons
    • Each button is defined inside the buttons list.
    • The "Play" button starts the animation from the current frame.
    • The "Pause" button stops it immediately.
    • direction="left" displays the buttons horizontally.

    Example of button configuration:

    updatemenus=[
        dict(
            type="buttons",
            direction="left",
            buttons=[
                dict(
                    label="Play",
                    method="animate",
                    args=[None, {"frame": {"duration": 300, "redraw": True}}]
                ),
                dict(
                    label="Pause",
                    method="animate",
                    args=[[None], {"frame": {"duration": 0, "redraw": False}}]
                )
            ]
        )
    ]
    

    Sliders The sliders property creates the timeline control under the chart. This slider lets you drag through each frame manually.

    How Sliders Work
    • Each slider step is linked to a frame by name.
    • Moving the slider updates the chart to show the corresponding frame.
    • You control animation speed by setting the duration inside each step.

    Example of a slider configuration:

    sliders=[
        {
            "active": 0,
            "steps": [
                dict(
                    method="animate",
                    args=[
                        [str(i)],
                        {"mode": "immediate",
                         "frame": {"duration": 300, "redraw": True}}
                    ],
                    label=str(i)
                )
                for i in range(numberOfFrames)
            ]
        }
    ]
    

    X-Axis Range Setting xaxis.range keeps the full timeline visible at all times so the animation doesn’t zoom or pan as the line grows.

    Controlling Axis Range

    Example of locking the x-axis:

    xaxis=dict(
        range=[startDate, endDate]
    )
    

    Tips for Customizing Animations

    Common Questions and Tips

    Why not use Plotly Express animation_frame? Plotly Express animations replace the entire dataset in each frame. If you want a line to build incrementally, you must use Graph Objects with cumulative frames.

    How do I change the animation speed? Adjust the duration value in each frame or slider step:

    "frame": {"duration": 300, "redraw": True}
    

    Smaller numbers = faster animation.

    Can I change the button positions? Yes—update the x and y values in updatemenus to reposition the buttons relative to the figure.

    ### Creating Faceted Line Charts with Plotly Express

    Faceted charts display multiple small plots in a single figure, each showing a subset of your data.
    This approach makes it easier to compare trends across different categories, like tickers or regions.

    Plotly Express provides built-in faceting with the facet_row and facet_col arguments.


    facet_row and facet_col
    • facet_row creates one row per unique category.
    • facet_col creates one column per unique category.
    • You can use them together to create a grid of panels.

    Example:

    facet_col="Ticker"
    

    This creates one column per ticker.


    facet_col_wrap

    If you have many categories, facet_col_wrap limits the number of columns before wrapping to the next row.

    Example:

    facet_col="Ticker",
    facet_col_wrap=2
    

    This creates 2 columns per row.


    Why Use Faceted Charts?

    Faceted charts help you:

    • Compare multiple time series side by side.
    • Keep each series scaled consistently.
    • See patterns that would be hard to spot in a single overlaid chart.

    Faceting is especially useful when your data has clear groupings you want to compare visually. ### Creating Subplots with make_subplots

    Plotly's make_subplots() lets you create a grid of charts and fully control what goes into each panel.

    This approach is more flexible than using facet_row and facet_col because:

    • You choose exactly which traces to include.
    • You decide how many rows and columns to use.
    • You can mix chart types in different panels.

    What is make_subplots?

    When you call make_subplots(), you define the structure of the figure, including:

    • Number of rows and columns
    • Whether axes are shared
    • Titles for each subplot

    Once you have the figure, you can add traces to individual panels.


    How shared_xaxes Works

    Setting shared_xaxes=True links all subplots to the same x-axis.
    This means:

    • Zooming or panning in one subplot updates all others.
    • Dates align across all panels for easier comparison.

    Adding Traces to Subplots

    After you create the figure, you use add_trace() to place each chart in a specific cell of the grid.

    For example:

    • The row argument specifies which row.
    • The col argument specifies which column.

    If you loop through multiple categories (like tickers), you can add each trace to a different row automatically.


    Subplot Titles

    The subplot_titles parameter creates a label above each panel. These titles help identify which data each subplot shows.


    Subplots are especially useful when you want to compare multiple groups side by side or stack several time series with shared dates.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.