# horizontal plot of confidence interval and values in matplotlib

I am working with Python with matplotlib and I would like to be able to plot values compared to given confidence interval so it would be easy to read.

Suppose I have the data:

```labelstr = [ 'name1','name2','name3' ]
values = [ 2.1, 40.5, 10.9 ]
lower_bound =  [ 1.8, 38.9 , 10.2 ]
upper_bound =  [ 2.3, 43.8 , 10.7 ]
```

I would like to plot the values with the corresponding confidence interval to show whether the value belongs or not. I am looking for a way to show the results horizontally. Ideally mark the point in a color if they belong and in a different color if they don’t.

I would also like the show the values for the points and the lower and upper bounds inside the plot.

Something in as in this example would convenient https://blog.uvm.edu/tbplante/2018/03/14/code-to-make-a-dot-and-95-confidence-interval-figure-in-stata/

any suggestions? thank you

Since you’ve already got aggregated values and bounds, use `Axes.errorbar` which accepts `xerr` for horizontal errors:

shape(2, N): Separate lower and upper values for each bar. First row contains the lower errors, the second row contains the upper errors.
Note that all error arrays should have positive values.

1. Convert the bounds to relative errors of shape 2xN:

```xerr = [
[value-lower for value, lower in zip(values, lower_bound)],
[upper-value for value, upper in zip(values, upper_bound)],
]

# [[0.30000000000000004, 1.6000000000000014, 0.7000000000000011],
#  [0.19999999999999973, 3.299999999999997, -0.20000000000000107]]
```

Note that when the documentation says these values should be positive, it assumes all your values fall within the bounds. In your example, 10.9 falls outside the upper bound of 10.7, so the negative value is expected and should stay negative.

2. Use `numpy.any` and `numpy.where` (or list comprehension) to generate a color array (orange if `xerr` is negative, else green):

```import numpy as np

inbounds = np.any(np.array(xerr) < 0, axis=0)
colors = np.where(inbounds, 'orange', 'green')

# array(['green', 'green', 'orange'], dtype='<U8')
```
3. Plot the values with `Axes.scatter`, errors with `Axes.errorbar`, and labels with `Axes.annotate`:

```import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.scatter(values, labelstr, c=colors, s=30, marker='|')
ax.set_xticks([])

ax.errorbar(values, labelstr, xerr=xerr,
fmt='none',     # don't connect data points
ecolor='black', # color of error lines
elinewidth=1,   # width of error lines
capsize=4,      # length of error caps
zorder=-1,      # put error bars behind scatter points
)

for value, lower, upper, label, color in zip(values, lower_bound, upper_bound, labelstr, colors):
shared = dict(xy=(value, label), color=color, textcoords='offset points', ha='center')
ax.annotate(value, xytext=(0, 5), va='bottom', **shared)
ax.annotate(f'[{lower}, {upper}]', xytext=(0, -5), va='top', **shared)
```