Reputation: 97
I'm attempting to display 2 major datasets namely "Type2" (red squares) and "Type1" (blue circles) in the legend. Nevertheless, since my plot involves subgroups of "Type1" and "Type2" (A,B are subgroups of each), there are 4 items appearing in the legend. Please take a look at how my plots looks like:
The issue is legend() tends to display 4 items : red square, red square, blue circle, blue cricle, while I need solely two of them i.e. red square to represent Type2 and blue circle for Type1.
Type2 Mean2 SD2
A 4.1 1.9
A 5.7 0.9
A 7.5 1.2
B 6.9 0.7
B 4.9 0.4
B 8.5 1
Type1 Mean1 SD1
A 8.1 1
A 7.7 0.9
A 8.5 1.1
B 5.9 0.4
B 7.9 0.7
B 9.5 1.2
Figure1 = plt.figure('Scatter Plot', figsize=(6,6), dpi=300)
Subplot1 = Figure1.add_subplot(1,1,1)
markers = ['s','s']
colors = ['r', 'r']
grouped = DataFrame.groupby('Type2')
for i,((g,d),m,c) in enumerate(zip(grouped,markers,colors)):
x = np.random.normal(loc=i,scale=0.2,size=(len(d['Mean2'],)))
Subplot1.errorbar(x, y= Mean2 , yerr= SD2 ,
fmt=m,
markersize=5, color=c,
capsize=3, markeredgewidth=0.5
)
XPos = list(range(len(grouped)))
Subplot1.set_xticks(XPos)
Subplot1.set_xticklabels([a for a in grouped.groups])
Subplot1.set_xlim(-0.5,1.5)
###############################################
###############################################
markers = ['o','o']
colors = ['b', 'b']
grouped = DataFrame.groupby('Type1')
for i,((g,d),m,c) in enumerate(zip(grouped,markers,colors)):
x = np.random.normal(loc=i,scale=0.2,size=(len(d['Mean1'],)))
Subplot1.errorbar(x, y= Mean1, yerr= SD1,
fmt=m,
markersize=5, color=c,
capsize=3, markeredgewidth=0.5
)
###############################################
###############################################
Subplot1.legend(['Type2','not needed!', 'Type1','not needed!'])
Any comments will be highly appreciated. Many thanks!
Upvotes: 0
Views: 45
Reputation: 36623
Matplotlib will only add items to the legend that have a label
affixed to them. You can use a ternary operation on the label assignment of the errorbar
to only give a label to the first iteration over each groubby object.
Example:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df1 = pd.DataFrame({'Type1': ['A', 'A', 'A', 'B', 'B', 'B'],
'y_mean1': [8.1, 7.7, 8.5, 5.9, 7.9, 9.5],
'y_SD1': [1.0, 0.9, 1.1, 0.4, 0.7, 1.2]})
df2 = pd.DataFrame({'Type2': ['A', 'A', 'A', 'B', 'B', 'B'],
'y_mean2': [4.1, 5.7, 7.5, 6.9, 4.9, 8.5],
'y_SD2': [1.9, 0.9, 1.2, 0.7, 0.4, 1.0]})
df1['x'] = np.random.rand(6)
df2['x'] = np.random.rand(6)
fix, ax = plt.subplots(1,1)
for i, (glab, g) in enumerate(df1.groupby('Type1')):
h1 = ax.errorbar(g.x,
g.y_mean1,
g.y_SD1,
fmt='o',
c='b',
capsize=3,
markeredgewidth=0.4,
elinewidth=0.4,
# label is only assigned on the first iteration
label='Type1' if not i else None)
for i, (glab, g) in enumerate(df2.groupby('Type2')):
h2 = ax.errorbar(g.x,
g.y_mean2,
g.y_SD2,
fmt='s',
c='r',
capsize=3,
markeredgewidth=0.4,
elinewidth=0.4,
# label is only assigned on the first iteration
label='Type2' if not i else None)
ax.legend()
Upvotes: 1