Case 1: a bar chart that hides the data
Diagnosis
Four bars with SEM whiskers and a row of asterisks. You can't tell how many samples sit behind each bar, and the two clusters in the Drug B group have been averaged into one mean that describes neither of them.
Treatment
Every sample is plotted, with the mean and 95% confidence interval beside it and the group size on the axis. The points share one colour because the axis already names the groups.
From the script
for i, (name, values) in enumerate(groups.items()):
# every sample, nudged sideways so the points do not overlap
x = i - 0.08 + rng.uniform(-0.14, 0.14, len(values))
ax.scatter(x, values, s=16, color=ACCENT, alpha=0.65, lw=0)
# mean and 95% confidence interval, drawn beside the points
low, high = ci95(values)
ax.plot([i + 0.26] * 2, [low, high], color=INK, lw=1.2)
ax.plot(i + 0.26, values.mean(), "o", color=INK, ms=4.5)