Skip to content

pandas plotting raises ValueError on style strings that should be valid according to spec. #21003

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Austrianguy opened this issue May 10, 2018 · 4 comments · Fixed by #33821
Closed
Labels
Milestone

Comments

@Austrianguy
Copy link

Austrianguy commented May 10, 2018

Code Sample

import pandas as pd
from numpy.random import random
import matplotlib.pyplot as plt

data = random((7,4))
fmt = 'd'

plt.plot(data, fmt, color='green') # works as expected (no error)

df = pd.DataFrame(data)
df.plot(color='green', style=fmt)

# The previous line raises ValueError:
# Cannot pass 'style' string with a color symbol and 'color' keyword argument.
# Please use one or the other or pass 'style' without a color symbol

Full Stack Trace

Traceback (most recent call last):

  File "<ipython-input-178-b2322b55aff5>", line 1, in <module>
    runfile('G:/irreplacable stuff/Scripts/playground/playground.py', wdir='G:/irreplacable stuff/Scripts/playground')

  File "C:\ProgramData\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "C:\ProgramData\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile
    exec(compile(scripttext, filename, 'exec'), glob, loc)

  File "G:/irreplacable stuff/Scripts/playground/playground.py", line 30, in <module>
    df.plot(color='green', style='d')

  File "C:\ProgramData\Anaconda2\lib\site-packages\pandas\plotting\_core.py", line 2677, in __call__
    sort_columns=sort_columns, **kwds)

  File "C:\ProgramData\Anaconda2\lib\site-packages\pandas\plotting\_core.py", line 1902, in plot_frame
    **kwds)

  File "C:\ProgramData\Anaconda2\lib\site-packages\pandas\plotting\_core.py", line 1727, in _plot
    plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)

  File "C:\ProgramData\Anaconda2\lib\site-packages\pandas\plotting\_core.py", line 931, in __init__
    MPLPlot.__init__(self, data, **kwargs)

  File "C:\ProgramData\Anaconda2\lib\site-packages\pandas\plotting\_core.py", line 182, in __init__
    self._validate_color_args()

  File "C:\ProgramData\Anaconda2\lib\site-packages\pandas\plotting\_core.py", line 215, in _validate_color_args
    "Cannot pass 'style' string with a color "

ValueError: Cannot pass 'style' string with a color symbol and 'color' keyword argument. Please use one or the other or pass 'style' without a color symbol

Problem description

df.plot should just pass the style kwarg as fmt arg to matplotlib.axes.plot but it does does some extra (sloppy) validation where it thinks that valid marker style symbols are color symbols and raises an error if the color is already defined elsewhere. The problem is clearly in _core.py, line 213.

This problem affects the following standard marker styles (key corresponds to m in the example code):

{u'd': u'thin_diamond',
 u'h': u'hexagon1',
 u'o': u'circle',
 u'p': u'pentagon',
 u's': u'square',
 u'v': u'triangle_down',
 u'x': u'x'}

Expected Output

df.plot(color='green', style=fmt) should simply plot the plot the same way as plt.plot(data, fmt, color='green') without raising errors. All legal values for fmt arg in pyplot.plot should be legal for the style kwarg in df.plot.

Output of pd.show_versions()

INSTALLED VERSIONS ------------------ commit: None python: 2.7.14.final.0 python-bits: 64 OS: Windows OS-release: 10 machine: AMD64 processor: Intel64 Family 6 Model 45 Stepping 7, GenuineIntel byteorder: little LC_ALL: None LANG: en LOCALE: None.None

pandas: 0.22.0
pytest: 3.5.0
pip: 9.0.3
setuptools: 39.0.1
Cython: 0.28.2
numpy: 1.14.2
scipy: 1.0.1
pyarrow: None
xarray: None
IPython: 5.6.0
sphinx: 1.7.2
patsy: 0.5.0
dateutil: 2.7.2
pytz: 2018.4
blosc: None
bottleneck: 1.2.1
tables: 3.4.2
numexpr: 2.6.4
feather: None
matplotlib: 2.2.2
openpyxl: 2.5.2
xlrd: 1.1.0
xlwt: 1.3.0
xlsxwriter: 1.0.4
lxml: 4.2.1
bs4: 4.6.0
html5lib: 1.0.1
sqlalchemy: 1.2.6
pymysql: None
psycopg2: None
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

@Austrianguy
Copy link
Author

I think this can be solved by changing the regex at _core.py line 213 and line 670 to '^[bgrcmykw]' or perhaps pulling the valid color letters directly from matplotlib.colors.BASE_COLORS.

@jbrockmendel jbrockmendel added the Visualization plotting label Aug 1, 2018
@joooeey
Copy link
Contributor

joooeey commented Apr 23, 2020

By Pandas 1.0.2 the issue has been partly fixed and the code sample runs fine now. However the same problem still persists when passing a list of colors as illustrated in the code sample below.

import pandas as pd
from numpy.random import random
import matplotlib.pyplot as plt

data = random((7,4))
fmt = 'd'

plt.plot(data, fmt, color='green') # works as expected (no error)

df = pd.DataFrame(data)
color = ['yellow', 'red', 'green', 'blue']
df.plot(color=color, style=fmt)

This can be fixed by changing pandas/plotting/matplotlib/core.py in the _apply_style_colors method line 727 from

nocolor_style = style is None or re.match("[a-z]+", style) is None

to

nocolor_style = style is None or re.match("[bgrcmykw]+", style) is None.

However, a real solution should pull the color letters from matplotlib.colors.BASE_COLORS.

By the way, I'm the same guy as Austrianguy. E-mail inboxes sometimes disappear. And passwords are forgotten.

@joooeey
Copy link
Contributor

joooeey commented Apr 26, 2020

I'm working on the bug fix. However I ran into the following issue when writing the test cases. The code above only fails during rendering. I included my code from 2018-05-10 and 2020-04-23 as tests in pandas/tests/plotting/test_frame.py. As expected the 2018 test passes. But unexpectedly the 2020 test passes too. I'm quite sure that is because when running the test suite the plot never renders so there's no opportunity for the error to raise. In fact the test suite doesn't even import matplotlib. Two options for the test suite: A) import matplotlib in the test. B) check that the output line colors are correct. I think I'll go for B.

Here's the traceback from running my 2020 code (copied from above) directly in Spyder:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_qt5.py", line 508, in _draw_idle
    self.draw()
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py", line 388, in draw
    self.figure.draw(self.renderer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\figure.py", line 1709, in draw
    renderer, self, artists, self.suppressComposite)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axes\_base.py", line 2647, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\lines.py", line 812, in draw
    self.get_markeredgecolor(), self._alpha)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py", line 177, in to_rgba
    rgba = _to_rgba_no_colorcycle(c, alpha)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py", line 240, in _to_rgba_no_colorcycle
    raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
ValueError: Invalid RGBA argument: ['yellow', 'red', 'green', 'blue']
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_qt5.py", line 508, in _draw_idle
    self.draw()
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py", line 388, in draw
    self.figure.draw(self.renderer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\figure.py", line 1709, in draw
    renderer, self, artists, self.suppressComposite)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axes\_base.py", line 2647, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\lines.py", line 812, in draw
    self.get_markeredgecolor(), self._alpha)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py", line 177, in to_rgba
    rgba = _to_rgba_no_colorcycle(c, alpha)
  File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py", line 240, in _to_rgba_no_colorcycle
    raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
ValueError: Invalid RGBA argument: ['yellow', 'red', 'green', 'blue']

@joooeey
Copy link
Contributor

joooeey commented Apr 27, 2020

related PR that was supposed to fix these issues: #29122

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants