How do I map categories to line styles in matplotlib?
Below is my attempt with the 'tips' data for illustration (please ignore the suitability of such a graph for this data).
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = sns.load_dataset('tips')
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
lines = {'Female':'dotted', 'Male':'solid'}
styles = df['sex'].apply(lambda x: lines[x])
ax1.plot(df['day'], df['total_bill'], c='darkorange', linestyle=styles)
ax2.plot(df['day'], df['tip'], c='steelblue', linestyle=styles)
ax1.set_xlabel('Day')
ax1.set_ylabel('Total Bill', color='darkorange')
ax2.set_ylabel('Tip', color='steelblue')
plt.show()
I've has success mapping colors this way, but I can't get it to work with linestyles. This is the error I get:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Edit:
Here is the full traceback
ValueError Traceback (most recent call last)
<ipython-input-28-271de52e7c48> in <module>
8 styles = df['sex'].apply(lambda x: lines[x])
9
---> 10 ax1.plot(df['day'], df['total_bill'], c='darkorange', linestyle=styles)
11 ax2.plot(df['day'], df['tip'], c='steelblue', linestyle=styles)
12
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
1663 """
1664 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D._alias_map)
-> 1665 lines = [*self._get_lines(*args, data=data, **kwargs)]
1666 for line in lines:
1667 self.add_line(line)
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/axes/_base.py in __call__(self, *args, **kwargs)
223 this += args[0],
224 args = args[1:]
--> 225 yield from self._plot_args(this, kwargs)
226
227 def get_next_color(self):
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs)
403 "non-matching shapes is deprecated.")
404 for j in range(max(ncx, ncy)):
--> 405 seg = func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
406 ret.append(seg)
407 return ret
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/axes/_base.py in _makeline(self, x, y, kw, kwargs)
310 default_dict = self._getdefaults(set(), kw)
311 self._setdefaults(default_dict, kw)
--> 312 seg = mlines.Line2D(x, y, **kw)
313 return seg
314
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/lines.py in __init__(self, xdata, ydata, linewidth, linestyle, color, marker, markersize, markeredgewidth, markeredgecolor, markerfacecolor, markerfacecoloralt, fillstyle, antialiased, dash_capstyle, solid_capstyle, dash_joinstyle, solid_joinstyle, pickradius, drawstyle, markevery, **kwargs)
375
376 self.set_linewidth(linewidth)
--> 377 self.set_linestyle(linestyle)
378 self.set_drawstyle(drawstyle)
379
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/lines.py in set_linestyle(self, ls)
1192
1193 # get the unscaled dashes
-> 1194 self._us_dashOffset, self._us_dashSeq = _get_dash_pattern(ls)
1195 # compute the linewidth scaled dashes
1196 self._dashOffset, self._dashSeq = _scale_dashes(
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/matplotlib/lines.py in _get_dash_pattern(style)
36 style = ls_mapper.get(style, style)
37 # un-dashed styles
---> 38 if style in ['solid', 'None']:
39 offset, dashes = None, None
40 # dashed styles
~/anaconda3/envs/py36v1/lib/python3.6/site-packages/pandas/core/generic.py in __nonzero__(self)
1553 "The truth value of a {0} is ambiguous. "
1554 "Use a.empty, a.bool(), a.item(), a.any() or a.all().".format(
-> 1555 self.__class__.__name__
1556 )
1557 )
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().