Ofek Glick
Ofek Glick

Reputation: 1003

How to plot multiple confidence intervals

I have a dataframe of confidence intervals of a multiple estimators.
The dataframe looks like this:

estimator lower bound upper bound
Estimator 1 -0.5 0.5
Estimator 2 -1 0.3
Estimator 3 -0.2 0.8
Estimator 4 0 0.2

I would like to use seaborn/matplotlib to plot out a single graph where all this confidence intervals are presented one on top of the other so the can be visually compared. I haven't been able to find a good enough example that shows how to do this so all help is welcome.

Also, I would like to mark the middle of the confidence interval to mark the estimator itself.
The graph would ideally look something like this: enter image description here

Upvotes: 3

Views: 1156

Answers (2)

Ofek Glick
Ofek Glick

Reputation: 1003

I found the code on github that created the graph presented in the question, thought I'd post it anyway:

import plotly.graph_objects as go

# List of Estimator valies
eta_estimators = [
    stable_ate,
    ipw_ate,
    dr_ate,
    conf_match,
]
# List of confidence intervals, All_CIs = [[lower_1,upper_1],...,[lower_n,upper_n]]
all_CIs = [
    stable_ate_ci,
    ipw_ate_ci,
    dr_ate_ci,
    conf_match_ci,
]
# Colors for each CI
colors = [
    "#636EFA",
    "#636EFA",
    "#e1ec00",
    "#EF553B"
]
# Names to be written above each CI
texts = [
    "Stabilized IPW",
    "IPW",
    "Doubly Robust",
    "Confounder Matching",
]

# plot the data
layout = go.Layout(title = f'title',yaxis = go.layout.YAxis(showticklabels=False))
fig = go.Figure(layout=layout)
# Set axes properties
min_val, max_val = all_CIs[0][0], all_CIs[0][0]
for idx_estimators, estimators in enumerate(eta_estimators):
    eta_value = estimators
    CI_left = all_CIs[idx_estimators][0]
    CI_right = all_CIs[idx_estimators][1]

    if CI_left < min_val:
        min_val = CI_left
    if CI_right > max_val:
        max_val = CI_right

    # Rectangle
    fig.add_shape(
        type="rect",
        x0=CI_left,
        y0=idx_estimators - 0.2,
        x1=CI_right,
        y1=idx_estimators + 0.2,
        line=dict(color="black", width=1),
        fillcolor=colors[idx_estimators],
    )

    # line
    fig.add_shape(
        type="line",
        x0=eta_value,
        y0=idx_estimators - 0.25,
        x1=eta_value,
        y1=idx_estimators + 0.25,
        line=dict(color="black"),
        fillcolor=colors[idx_estimators],
    )

    # text
    fig.add_trace(
        go.Scatter(
            x=[(CI_right + CI_left) / 2],
            y=[idx_estimators + 0.35],
            text=[texts[idx_estimators]],
            mode="text",
            showlegend=False,
        )
    )

dif = max_val - min_val
fig.update_xaxes(range=[min_val - 0.1 * dif, max_val + 0.1 * dif], showgrid=False)
fig.update_yaxes(range=[-0.5, 8])
fig.show()

This can be copy and pasted and all that needs to be changed is the values at the beginning of the code.

Upvotes: 2

INGl0R1AM0R1
INGl0R1AM0R1

Reputation: 1628

Well lets start up with well the beginning, this will give you a series of plots that are well equivalent to you wanted distances. All of the objects are configurable

data_dict['category'] = ['Estimator 1','Estimator 2','Estimator 3','Estimator 4']
data_dict['lower'] = [-0.5,-1,-0.2,0]
data_dict['upper'] = [0.5,0.3,0.8,0.2]

df = pd.DataFrame(data_dict)


for l,u,y  in zip(df['lower'],df['upper'],range(len(df))):
      plt.plot((l,u),(y,y),'ro-',color='orange')
plt.yticks(range(len(df)),list(df['category']))

Now to your middle check well i would just create single points.

df['median'] = (df['lower'] + df['upper'])/2

for x,y in zip(df['median'],np.arange(len(df))):
     plt.plot(x, y, marker="o)

This will give you somethinng really close to what you want after that just try configuring the objects and the yscales and boom paraboom

Upvotes: 1

Related Questions