Bukaida
Bukaida

Reputation: 235

Multiple maximum labelling matplotlib

I am trying to label multiple maximum but unable to display them properly. Also the label is appearing too far from the point overlapping with the legend.

import matplotlib.pyplot as plt
import numpy as np

x1,y1= np.loadtxt('MaxMin1.txt', dtype=str, unpack=True)

x1 = x1.astype(int)
y1 = y1.astype(float)

x2,y2= np.loadtxt('MaxMin2.txt', dtype=str, unpack=True)

x2 = x2.astype(int)
y2 = y2.astype(float)

x3,y3= np.loadtxt('MaxMin3.txt', dtype=str, unpack=True)

x3 = x3.astype(int)
y3 = y3.astype(float)

#-------------------------------------------------------------
def annot_max(x,y, ax=None):
    xmax = x[np.argmax(y)]
    ymax = y.max()
    text= "x={:.3f}, y={:.3f}".format(xmax, ymax)
    if not ax:
        ax=plt.gca()
    bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
    arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=60")
    kw = dict(xycoords='data',textcoords="axes fraction",
              arrowprops=arrowprops, bbox=bbox_props, ha="left", va="top")
    ax.annotate(text, xy=(xmax, ymax), xytext=(0.94,0.96), **kw)


#-------------------------------------------------------------

fig=plt.figure()
fig.show()
ax=fig.add_subplot(111)

ax.plot(x1,y1,c='b',ls='-',label='Recovery',fillstyle='none')
ax.plot(x2,y2,c='g',ls='-',label='Normal')
ax.plot(x3,y3,c='r',ls='-',label='No-Recovery')
annot_max(x1,y1)
annot_max(x2,y2)
annot_max(x3,y3)
plt.legend(loc=1)

# naming the x axis 
plt.xlabel('<------Instances(count)------>') 
# naming the y axis 
plt.ylabel('Acceleration (m/sq.sec)') 
# giving a title to my graph 
plt.title('Fall Detection Comparison graph')

plt.show()

And the output I got Output Graph I am just beginning with python so very small hint may not be understandable by me.Please help.

Upvotes: 5

Views: 4130

Answers (1)

Serenity
Serenity

Reputation: 36635

You need yo change function annot_max. First of all, all your labels appear in the same place according to xytext=(0.94,0.96). You have to specify label position according to coordinates of xmax and ymax as below.

Then change textcoords to data value to manipulate a label position according to data not axes fraction. In my example xytext=(xmax+.5,ymax+5) means that location of label box will shifted by +.5 point from xmax and +5 points by ymax (you have to use your own values according to your data).

But I recommend to place your labels manually since you have 3 maximum (specify a location of every label box in argument xytext like xytext=(100,40) - your 1st maximum).

Matplotlib can not avoid overlapping of text boxes automatically.

To squeeze label box you can place text in two rows, i.e., text= "x={:.3f},\ny={:.3f}".format(xmax, ymax).

import matplotlib.pyplot as plt
import numpy as np

x1=np.array([1,2,3,4,5,6,7,8,9,10])
x2 = x1[:]
x3 = x1[:]
y1=np.array([1,2,3,100,5,6,7,8,9,10])
y2=np.array([50,2,3,4,5,6,7,8,9,10])
y3=np.array([1,2,3,4,5,6,75,8,9,10])

#-------------------------------------------------------------
def annot_max(x,y, ax=None):
    xmax = x[np.argmax(y)]
    ymax = y.max()
    text= "x={:.3f}, y={:.3f}".format(xmax, ymax)
    if not ax:
        ax=plt.gca()
    bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
    arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=60")
    kw = dict(xycoords='data',textcoords="data",
              arrowprops=arrowprops, bbox=bbox_props, ha="left", va="top")
    ax.annotate(text, xy=(xmax, ymax), xytext=(xmax+.5,ymax+5), **kw)


#-------------------------------------------------------------

fig=plt.figure()
fig.show()
ax=fig.add_subplot(111)

ax.plot(x1,y1,c='b',ls='-',label='Recovery',fillstyle='none')
ax.plot(x2,y2,c='g',ls='-',label='Normal')
ax.plot(x3,y3,c='r',ls='-',label='No-Recovery')
annot_max(x1,y1)
annot_max(x2,y2)
annot_max(x3,y3)
plt.legend(loc=1)

# naming the x axis 
plt.xlabel('<------Instances(count)------>') 
# naming the y axis 
plt.ylabel('Acceleration (m/sq.sec)') 
# giving a title to my graph 
plt.title('Fall Detection Comparison graph')

plt.show()

enter image description here

Upvotes: 4

Related Questions