6. Creating Heat maps#

Heat map charts are a versatile data visualization technique that uses color to represent values in a two-dimensional matrix or grid. Each cell in the heat map corresponds to a combination of two variables, and the color intensity or hue indicates the magnitude of the data point. This approach makes it easy to identify patterns, trends, and outliers across large datasets. Heat maps are particularly useful when working with data that has a natural tabular structure, such as correlation matrices, sales performance by product and region, or time-series data by categories.

One powerful application of heat maps is in illustrating yield curves’ term structures over time. In this context, the x-axis could represent time (e.g., months or years), while the y-axis shows the maturity periods of bonds (e.g., 3 months, 2 years, 10 years). The color in each cell would reflect the yield for a given maturity at a specific time, allowing analysts to quickly observe changes in interest rate environments and identify trends like steepening or flattening yield curves. This makes heat maps an invaluable tool for financial professionals seeking insights into interest rate dynamics.

Despite their utility, heat maps should be avoided in cases where precise numerical values are critical, as the reliance on color gradation can obscure exact measurements. They are also less effective when the dataset is small or lacks meaningful variability, as the visualization may appear sparse or uninformative. Additionally, choosing an inappropriate color scale or failing to consider colorblind accessibility can lead to misinterpretation. Heat maps work best when the goal is to identify high-level patterns and trends across large datasets, rather than focusing on detailed or highly specific comparisons.

Getting ready#

For this recipe we will use data from the Federal Reserve Economic Data which is saved in a spreadsheet

  1. Import the pandas Python library as pd

import pandas as pd
  1. Use the function read_csv to read the data. Make sure you set the argument parse_dates as True to guarantee that the dates are being parsed correctly

data = pd.read_csv('data/data_fed_yc.csv', parse_dates=True).set_index('DATE')
  1. Inspect the data by calling the method head on the DataFrame

data.head()
30-year 10-year 5-year 3-year 2-year 1-year 6-month 3-month 1-month
DATE
1990-01-31 8.26 8.21 8.12 8.13 8.09 7.92 7.96 7.90 NaN
1990-02-28 8.50 8.47 8.42 8.39 8.37 8.11 8.12 8.00 NaN
1990-03-31 8.56 8.59 8.60 8.63 8.63 8.35 8.28 8.17 NaN
1990-04-30 8.76 8.79 8.77 8.78 8.72 8.40 8.27 8.04 NaN
1990-05-31 8.73 8.76 8.74 8.69 8.64 8.32 8.19 8.01 NaN
  1. Transpose the DataFrame to have the tenors as indices and the dates as columsn. This will facilitate making the heatmap

data = data.T
data = data.iloc[::-1] 
data.head()
DATE 1990-01-31 1990-02-28 1990-03-31 1990-04-30 1990-05-31 1990-06-30 1990-07-31 1990-08-31 1990-09-30 1990-10-31 ... 2023-07-31 2023-08-31 2023-09-30 2023-10-31 2023-11-30 2023-12-31 2024-01-31 2024-02-29 2024-03-31 2024-04-30
1-month NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 5.39 5.54 5.53 5.57 5.53 5.54 5.54 5.49 5.51 5.48
3-month 7.90 8.00 8.17 8.04 8.01 7.99 7.87 7.69 7.60 7.40 ... 5.49 5.56 5.56 5.60 5.52 5.44 5.45 5.44 5.47 5.44
6-month 7.96 8.12 8.28 8.27 8.19 8.05 7.92 7.77 7.70 7.53 ... 5.53 5.54 5.51 5.57 5.44 5.34 5.21 5.28 5.36 5.38
1-year 7.92 8.11 8.35 8.40 8.32 8.10 7.94 7.78 7.76 7.55 ... 5.37 5.37 5.44 5.42 5.28 4.96 4.79 4.92 4.99 5.14
2-year 8.09 8.37 8.63 8.72 8.64 8.35 8.16 8.06 8.08 7.88 ... 4.83 4.90 5.02 5.07 4.88 4.46 4.32 4.54 4.59 4.87

5 rows × 412 columns

How to do it#

  1. Import the plotly.graph_objects module as go

import plotly.graph_objects as go
  1. Make a minimal heat-map using the function Heatmap from the go module. You need to specify the following three key arguments

  • x

  • y

  • z

The data that describes the heatmap value-to-color mapping is set in z. Data in z can either be a 2D list of values (ragged or not) or a 1D array of values. In the case where z is a 2D list, say that z has N rows and M columns. Then, by default, the resulting heatmap will have N partitions along the y axis and M partitions along the x axis. In other words, the i-th row/ j-th column cell in z is mapped to the i-th partition of the y axis (starting from the bottom of the plot) and the j-th partition of the x-axis (starting from the left of the plot). This behavior can be flipped by using transpose.

Moreover, x (y) can be provided with M or M+1 (N or N+1) elements. If M (N), then the coordinates correspond to the center of the heatmap cells and the cells have equal width. If M+1 (N+1), then the coordinates correspond to the edges of the heatmap cells. In the case where z is a 1D list, the x and y coordinates must be provided in x and y respectively to form data triplets.

fig = go.Figure(data=[go.Heatmap(x=data.columns,
                                 y=data.index,
                                 z=data.values,
                                )])

fig.show()
  1. Change the color palette in the Heatmap by using the argument colorscale. In this case, we specify it to ‘ice’ but it can be the bame of any colorscale available in Plotly

fig = go.Figure(data=[go.Heatmap(z=data.values,
                                    x=data.columns,
                                    y=data.index,
                                    colorscale='ice',
                                    )])

fig.show()
  1. Reverse the way the color scale is mapped into the z values by setting the argument reversescale to True. In this case, this case the effect of mapping lighter (darker) blue tones to lower (higher) percentage points.

fig = go.Figure(data=[go.Heatmap(z=data.values,
                                    x=data.columns,
                                    y=data.index,
                                    colorscale='ice',
                                    reversescale=True,
                                    )])

fig.show()
  1. Customise the information available in the hover box as well as its format by using the argument hovertemplate. Note that we are using HTML elements to define the formatting

fig = go.Figure(data=[go.Heatmap(z=data.values,
                                    x=data.columns,
                                    y=data.index,
                                    colorscale='ice',
                                    reversescale=True,
                                    hovertemplate='<br>Date: %{x}' + \
                                    '<br>Maturity: %{y}' + \
                                    '<br>Yield: %{z:.2f}<extra></extra>',
                                    )])

fig.show()
  1. Use the method update_layout to customise the following elements in the Figure object

  • title

  • title_x

  • title_font

  • width and height

  • template

fig = go.Figure(data=[go.Heatmap(z=data.values,
                                 x=data.columns,
                                 y=data.index,
                                 colorscale='ice',
                                 reversescale=True,
                                 hovertemplate='<br>Date: %{x}' + \
                                                '<br>Maturity: %{y}' + \
                                                '<br>Yield: %{z:.2f}<extra></extra>',
                                 )])

fig.update_layout(title='A Heatmap of the Yield Curve Evolution over Time',
                  title_x=0.5,
                  title_font={'size':18},
                  width=1000,
                  height=600,
                  template='plotly_white'
                )


fig.show()