Search code examples
pythonnumpymatplotlibseaborn

How to show the results and confidence interval values together?


I have two 10x10 matrices. One of them is for main results and the other one is for confidence interval (CI) of the corresponding element in the main results matrix.

I am wondering how I can show both of them

equation

in one matrix in a pretty way?

right now I have each of them as the following

x, y = np.random.rand(2, 1000) * 1
fig, ax = plt.subplots(figsize=(12, 10))
hist, xedges, yedges = np.histogram2d(
    x, y, bins=10, range=[[0, 1], [0, 1]]
)
xedges = np.round(xedges, 2)
yedges = np.round(yedges, 2)
ax = sns.heatmap(
    hist.T, annot=True, fmt='6.6g', linewidths=0.5, linecolor='b', center=True
)
ax.set_xticks(np.arange(len(xedges)), xedges)
ax.set_yticks(np.arange(len(yedges)), yedges, rotation=0)
ax.set(title='Results')
ax.invert_yaxis()
plt.show()

enter image description here

and

x, y = np.random.rand(2, 1000) * 1
fig, ax = plt.subplots(figsize=(12, 10))
hist_ci, xedges, yedges = np.histogram2d(
    x, y, bins=10, range=[[0, 1], [0, 1]]
)
xedges = np.round(xedges, 2)
yedges = np.round(yedges, 2)
ax = sns.heatmap(
    hist_ci.T, annot=True, fmt='6.6g', linewidths=0.5, linecolor='b', center=True
)
ax.set_xticks(np.arange(len(xedges)), xedges)
ax.set_yticks(np.arange(len(yedges)), yedges, rotation=0)
ax.set(title='CI')
ax.invert_yaxis()
plt.show()

enter image description here

I want to know if I can display both of them in one figure in a way that we have plus/minus sign in between of them?


Solution

  • Instead of simply being True, annot can also be a matrix of strings to be displayed. Such a matrix can be constructed from the two given matrices. If needed, a \n can be inserted into the string to print it on two lines.

    import matplotlib.pyplot as plt
    import seaborn as sns
    import numpy as np
    
    x, y = np.random.rand(2, 1000) * 1
    hist, xedges, yedges = np.histogram2d(x, y, bins=10, range=[[0, 1], [0, 1]])
    xedges = np.round(xedges, 2)
    yedges = np.round(yedges, 2)
    
    x_ci, y_ci = np.random.rand(2, 1000) * 1
    hist_ci, _, _ = np.histogram2d(x_ci, y_ci, bins=10, range=[[0, 1], [0, 1]])
    fig, ax = plt.subplots(figsize=(12, 10))
    annot = [[f"{val:.6g}±{ci:.6g}" for val, ci in zip(row, row_ci)]
             for row, row_ci in zip(hist.T, hist_ci.T)]
    ax = sns.heatmap(hist.T, annot=annot, fmt='', linewidths=0.5, linecolor='b')
    ax.set_xticks(np.arange(len(xedges)), xedges)
    ax.set_yticks(np.arange(len(yedges)), yedges, rotation=0)
    ax.set(title='Results')
    ax.invert_yaxis()
    plt.show()
    

    seaborn heatmap with confidence intervals

    PS: Note that center=True is not a valid value in sns.heatmap(). center is meant to be an optional floating-point value for centering the colors.