Reputation: 583
I am trying to plot an interval style plot, as shown in the code below. I am using a look to achieve this. However, when I try and view the legend, multiple legend elements are plotted from each catagory.
How can I plot it that only a single element of the legend shows i.e only one A and B entry?
Thanks.
import matplotlib.pyplot as plt
import pandas as pd
data = pd.DataFrame({'code':['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
'd1':[1,2,3,4,5,1,2,3,4,5],
'd2':[2,3,4,5,6,2,3,4,5,6]})
f, ax = plt.subplots(1,1)
for lab, col in zip(['A', 'B'], ['red', 'green']):
_ = data[data['code'] == lab]
ax.plot((_['code'].values[0], _['code'].values[0]), (_['d1'], _['d2']),
label = lab, color = col)
ax.legend()
Upvotes: 0
Views: 50
Reputation: 39072
An alternate solution could look like
from collections import OrderedDict
# rest of the code
for lab, col in zip(['A', 'B'], ['red', 'green']):
_ = data[data['code'] == lab]
ax.plot((_['code'].values[0], _['code'].values[0]), (_['d1'], _['d2']),
label = lab , color = col)
i +=1
ax.legend()
handles, labels = ax.get_legend_handles_labels()
unique = OrderedDict(zip(labels, handles))
ax.legend(unique.values(), unique.keys())
Upvotes: 1
Reputation: 5686
You were almost there. You were correctly extracting the x-values for the plotting, however, you'd forgotten to do the same for the y-values. Because of this you were creating a legend entry for every y-value.
Instead of using (_['d1'], _['d2'])
in your call to ax.plot
you probably wanted something like (_['d1'].values.min(), _['d2'].values.max())
:
import matplotlib.pyplot as plt
import pandas as pd
data = pd.DataFrame({'code':['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
'd1':[1,2,3,4,5,1,2,3,4,5],
'd2':[2,3,4,5,6,2,3,4,5,6]})
f, ax = plt.subplots(1,1)
for lab, col in zip(['A', 'B'], ['red', 'green']):
_ = data[data['code'] == lab]
ax.plot((_['code'].values[0], _['code'].values[0]), (_['d1'].values[0], _['d2'].values[-1]),
label = lab, color = col)
ax.legend()
Upvotes: 1