Отобразить строковые значения в стиль линии в Matplotlib - PullRequest
0 голосов
/ 08 апреля 2020

Как мне сопоставить категории со стилями линий в matplotlib?

Ниже приведена моя попытка с данными «подсказок» для иллюстрации (пожалуйста, игнорируйте пригодность такого графика для этих данных).

    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()

У меня есть успех, отображающий цвета таким образом, но я не могу заставить его работать с линейными стилями. Это ошибка, которую я получаю:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

Редактировать:

Вот полный возврат

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().

1 Ответ

0 голосов
/ 09 апреля 2020

Похоже, вы хотите использовать sns.lineplot(), который позволяет разделить ваш набор данных в соответствии с категориальным столбцом и изменить способ отображения каждой строки (по цвету, используя hue=, или по стилю, используя style=.

df = sns.load_dataset('tips')
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

lines = {'Female':(1,3), 'Male':''}
sns.lineplot(ax=ax1, data=df, x='day', y='total_bill', color='darkorange', style='sex', dashes=lines, estimator=None)
sns.lineplot(ax=ax2, data=df, x='day', y='tip',  color='steelblue', style='sex', dashes=lines, estimator=None)

ax1.set_xlabel('Day')
ax1.set_ylabel('Total Bill', color='darkorange')
ax2.set_ylabel('Tip', color='steelblue')

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...