Aligning markers for individual points in matplotlib and removing "double"
legend for markers
I am trying to figure out the alignment of Markers in "ax.plot" . Apart
from plotting 2 bar graphs, I also need to plot 2 points, one per bar
graph. Here's what I am looking for -:
Centering/alignment of markers ('o' and '' here, in the center of each
bar, rather than at the edge of the bar graph. "o" should come at the
center of the 1st bar graph and "" should come at the center of the 2nd
bar graph, their individual heights will differ though, as on the scale
"Performance" -the "o" and "" are "Performance" objects (right hand side
scale, as in the figure) - centering, thus means, overlay of the
markers("o" and "" against its respective stacked graph.
Removing the duplicate marker symbols, with 'o' and '*' in the legend on
the upper right corner. And, understanding why that happens for par2.plot
, but not for ax.bar object. Could I have done this without using
ax.twinx(), which generates two scales (one for "#candidates" and other
for "Performance" - and if this double entry of legend is related to using
the 2 scales ? (I hope not)
For (2), I also used plt.legend(numpoints=1) just before the last line,
plt,show() according to the answer here, multiple markers in legend , but
that didn't seem to remove the "duplicate markers" in this context.
Also attached is the graph, with (1) and (2) highlighted
Tip -: Ignore the looping constructs, they are a part of the larger piece,
and did not want to change that while pasting, focus on this snippet of
the entire code (IMO, this should narrow the problem?)
rects1 = ax.bar(ind, Current_Period, width, color=colors)
rects2 = ax.bar(ind+width, Next_Period, width, color='c')
lines_1=par1.plot(perform_1,linestyle='', marker='H', markerfacecolor ='k')
lines_2=par1.plot(perform_2,linestyle='', marker='*',markerfacecolor ='m')
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time
period', 'Next time Period','Current Period Performance', 'Next Period
Performance'),prop=dict(size=10) )
Here is the complete code that I used -:
#Final plotting file
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
#placing anchored text within the figure
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
rc('mathtext', default='regular')
history_P=[[1.4155322812819471, 4.9723842851306213, 3.6831354714462456,
3.0345047089322521, 5.3355879766963819], [2.3240101637275856,
4.7804345245879354, 7.0829471987293973, 6.1050663075245852,
3.6087166298399973], [3.5770722538162265, 3.4516290562530587,
4.4851829512197678, 5.1158026103364733, 3.7873662329909235],
[4.7137003352158136, 5.0792119756378593, 4.4624078437179504,
3.1790266221827754, 4.8711126648436895], [4.8043291762010414,
5.6979872315568576, 3.4869780377350339, 3.892755123606721,
3.8142509389863095], [4.8072846135271492, 4.2055137431209033,
5.0441056822018417, 4.1014759291893306, 5.327936039526822]]
history_C=[[14000, 14000, 14000, 14000, 14000], [5373, 18874, 13981,
11519, 20253], [6806, 14001, 20744, 17880, 10569], [12264, 11834, 15377,
17540, 12985], [14793, 15940, 14004, 9977, 15286], [15500, 18384, 11250,
12559, 12307]]
N = 5
ind = np.arange(N) # the x locations for the groups
width = 0.35
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.itervalues():
sp.set_visible(False)
def autolabel(rects):
# attach some text labels
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x()+rect.get_width()/2., 1.05*height,
'%d'%int(height),ha='center', va='bottom')
alphab = ['M1', 'M2', 'M3', 'M4', 'M5', 'M6']
for k in range(0,5):
colors=[]
Current_Period=history_C[k]
Next_Period = history_C[k+1]
perform_1=history_P[k]
perform_2=history_P[k+1]
for i in range(0,5):
if perform_1[i]==max(perform_1) :
colors.append('g')
best=i
elif perform_1[i]==min(perform_1):
colors.append('r')
worst=i
elif (perform_1[i] != min(perform_1) or perform_1[i] !=
max(perform_1)):
colors.append('b')
fig, ax = plt.subplots()
fig.subplots_adjust(right=0.75)
par1 = ax.twinx()
make_patch_spines_invisible(par1)
rects1 = ax.bar(ind, Current_Period, width, color=colors)
rects2 = ax.bar(ind+width, Next_Period, width, color='c')
lines_1=par1.plot(perform_1,linestyle='', marker='H', markerfacecolor
='k')
lines_2=par1.plot(perform_2,linestyle='', marker='*',markerfacecolor
='m')
ax.set_xlabel("Model #",style='italic',size='large')
ax.set_ylabel("Candidate #",style='italic',size='large')
par1.set_ylabel("Performance",style='italic',size='large')
ax.set_title('Aggregated Performace Rolled out to candidates, per
period',style='italic')
#fontdict=dict('fontsize':rcParams['axes.titlesize'],'verticalalignment':
'baseline', 'horizontalalignment': loc)
ax.set_xticks(ind+width)
ax.set_xticklabels( ('M1', 'M2', 'M3', 'M4', 'M5') )
ax.annotate('Worst Performer', xy=(worst,0),
xycoords='data',xytext=(-30, 30), textcoords='offset points',size=12,
va="center", ha="center",arrowprops=dict(arrowstyle="simple",
connectionstyle="arc3,rad=-0.2"))
ax.annotate('Best Performer', xy=(best,0),
xycoords='data',xytext=(-30, 30), textcoords='offset points',size=12,
va="center", ha="center",arrowprops=dict(arrowstyle="simple",
connectionstyle="arc3,rad=-0.2"))
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time
period', 'Next time Period','Current Period Performance', 'Next Period
Performance'),prop=dict(size=10) )
#placing anchored text within the figure, per Period
at = AnchoredText("Time Period :"+str(k+1),prop=dict(size=10),
frameon=True,loc=2,)
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
par1.set_ylim(0, 10)
autolabel(rects1)
autolabel(rects2)
plt.show()
No comments:
Post a Comment