Home > Mobile >  Python: Annotate max value of bar graph: string x, int y
Python: Annotate max value of bar graph: string x, int y

Time:10-08

1-week old newbie here. I've successfully created a chart showing states on the x-axis and rate on the y-axis. I'm struggling trying to annotate the max value, e.g. Maine @ 1.10%. Below works fine, but it's manual in that I'm plugging in the coordinates:

ax.annotate('Biggest Concern',
        xy=(11.8, 1), xycoords='data',
        xytext=(-15, 25), textcoords='offset points',
        arrowprops=dict(facecolor='black', shrink=0.05),
        horizontalalignment='right', verticalalignment='bottom')

When I try this approach:

x=np.array(df_Readmit['State'])              
y=np.array(df_Readmit['DeltaReadmitRate'])   
ax.annotate('local max', xy=(xmax, ymax), xytext=(xmax, ymax 5),
            arrowprops=dict(facecolor='black', shrink=0.05),)

it errors out:

can only concatenate str (not "int") to str

I tried wrapping str() around the ymax 5 and I receive the same message. Below is the almost finished product, just missing the annotations. I assume need to do something w/the index to make the states an int.

enter image description here

CodePudding user response:

If 5 for the value of ymax, the annotation may be outside the graph frame. In the case of categorical variables, we may get the index of the maximum value, so we use it. So, by indexing the maximum of the y-value and the maximum of the x-value, it is possible to annotate. The offset value should be adjusted to match the y-axis value.

Since no data was presented, I am creating sample data.

df.head()
    short_name  state   Delta
0   AK  Alaska  -0.257858
1   AL  Alabama     0.918444
2   AR  Arkansas    -1.101622
3   AZ  Arizona     1.957581
4   CA  California  1.143238

fig, ax = plt.subplots(figsize=(16,6))

ax.bar(df['state'], height=df['Delta'], color=['b' if x > 0 else 'r' for x in df['Delta']])
ax.grid()
ax.set_xlim([df.index[0]-0.5, df.index[-1] 0.5])
ax.set_ylim([-2.2,2.2])

xmax = df['Delta'].argmax()
ymax = df['Delta'].max()
ax.annotate('local max', xy=(xmax, ymax), xytext=(xmax, ymax 0.2),
            arrowprops=dict(facecolor='black', shrink=0.05),)
ax.tick_params(axis='x', labelrotation=90)
for s in ['top','bottom','right','left']:
    ax.spines[s].set_visible(False)
plt.show()

enter image description here

  • Related