Skip to content

VIS: Allow 'C0'-like plotting for plotting colors #15516 #15873

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

Merged
merged 5 commits into from
Apr 12, 2017

Conversation

GuessWhoSamFoo
Copy link
Contributor

Defined special case for 'CN' cases where N is 0 to 9. There may be custom color cycles that can also be parsed as a single color so the ValueError message is left intact (unless this is false).

running: pytest --skip-slow --skip-network pandas
============================= test session starts ==============================
platform linux2 -- Python 2.7.13, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
rootdir: /home/sfoo/pandas, inifile: setup.cfg
collected 11894 items / 3 skipped 

10234 passed, 1586 skipped, 77 xfailed, 2084 pytest-warnings in 486.80 seconds 

@jreback jreback added the Visualization plotting label Apr 3, 2017
@@ -177,6 +177,7 @@ Other enhancements
- The ``usecols`` argument in ``pd.read_csv`` now accepts a callable function as a value (:issue:`14154`)
- The ``skiprows`` argument in ``pd.read_csv`` now accepts a callable function as a value (:issue:`10882`)
- ``pd.DataFrame.plot`` now prints a title above each subplot if ``suplots=True`` and ``title`` is a list of strings (:issue:`14753`)
- ``pd.DataFrame.plot`` can pass matplotlib 2.0 default color cycle as a single string as color parameter (:issue:`15516`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you put a pointer into mpl docs (or pandas docs) about these color.

@@ -141,6 +141,12 @@ def test_plot(self):
result = ax.get_axes() # deprecated
self.assertIs(result, axes[0])

def test_mpl2_color_cycle_str(self):
colors = ['C' + str(x) for x in range(10)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add the issue number as a comment

msg = ("'{0}' can be parsed as both single color and "
"color cycle. Specify each color using a list "
"like ['{0}'] or {1}")
raise ValueError(msg.format(colors, list(colors)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment here about what you are doing

"color cycle. Specify each color using a list "
"like ['{0}'] or {1}")
raise ValueError(msg.format(colors, list(colors)))
if color[0] == 'C' and len(color) == 2:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could in theory break if color=''?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a ZeroDivisionError when trying to handle cases where there are more lines than specified colors (or vice versa). Probably can add a try/except block here

In matplotlib, passing color='' causes ValueError: Invalid RGBA argument: ''. I could add a more meaningful error message for this case as part of this PR.

@codecov
Copy link

codecov bot commented Apr 4, 2017

Codecov Report

Merging #15873 into master will increase coverage by <.01%.
The diff coverage is 50%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #15873      +/-   ##
==========================================
+ Coverage   90.99%   90.99%   +<.01%     
==========================================
  Files         143      143              
  Lines       49479    49481       +2     
==========================================
+ Hits        45021    45023       +2     
  Misses       4458     4458
Flag Coverage Δ
#multiple 88.75% <50%> (+0.01%) ⬆️
#single 40.63% <0%> (-0.12%) ⬇️
Impacted Files Coverage Δ
pandas/tools/plotting.py 72.27% <50%> (+0.5%) ⬆️
pandas/io/gbq.py 25% <0%> (-58.34%) ⬇️
pandas/core/frame.py 97.56% <0%> (-0.1%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cd24fa9...e249722. Read the comment docs.

@codecov
Copy link

codecov bot commented Apr 4, 2017

Codecov Report

Merging #15873 into master will increase coverage by 0.07%.
The diff coverage is 77.77%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #15873      +/-   ##
==========================================
+ Coverage   90.95%   91.03%   +0.07%     
==========================================
  Files         145      145              
  Lines       49534    49582      +48     
==========================================
+ Hits        45056    45136      +80     
+ Misses       4478     4446      -32
Flag Coverage Δ
#multiple 88.8% <77.77%> (+0.07%) ⬆️
#single 40.57% <0%> (-0.09%) ⬇️
Impacted Files Coverage Δ
pandas/tools/plotting.py 72.47% <77.77%> (+0.71%) ⬆️
pandas/indexes/frozen.py 91.17% <0%> (-2.38%) ⬇️
pandas/core/indexing.py 94.01% <0%> (-0.1%) ⬇️
pandas/core/internals.py 93.54% <0%> (-0.08%) ⬇️
pandas/core/series.py 94.89% <0%> (-0.08%) ⬇️
pandas/indexes/base.py 96.09% <0%> (-0.06%) ⬇️
pandas/core/reshape.py 99.27% <0%> (-0.01%) ⬇️
pandas/tslib.py 100% <0%> (ø) ⬆️
pandas/__init__.py 92.68% <0%> (ø) ⬆️
pandas/tseries/tools.py 85.55% <0%> (ø) ⬆️
... and 14 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ba30e3a...9d15e7d. Read the comment docs.

# for supporting matplotlib < 2.0.0
if re.match(r'C[0-9]', colors) and len(colors) == 2:
prop_cycler = plt.rcParams['axes.prop_cycle']
hex_color = prop_cycler.by_key().get('color', ['k'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this prop_cycler is also only supported for matplotlib versions >= 1.5?

See here how it is handled at another location: https://github.com/GuessWhoSamFoo/pandas/blob/e2497222ecf64e07f4bd7873a1b860021b0b605c/pandas/tools/plotting.py#L185-L190

@GuessWhoSamFoo
Copy link
Contributor Author

In order to pass tests on matplotlib 1.5, converting C[0-9] to a hex code works, but the tests are not as meaningful since there are already tests for that.

@jorisvandenbossche
Copy link
Member

Maybe we shouldn't try to support matplotlib versions < 2.0.0 ? It is only a feature from that version? The we also don't have the problem of failing tests on older matplotlib version (as the test could just be skipped for those)
On the other hand it is not that difficult to convert to hex color

for c in list(plt.rcParams['axes.prop_cycle'])]
df = DataFrame(randn(10, 3), columns=['a', 'b', 'c'])
for c in colors:
_check_plot_works(df.plot, color=hex_color[int(c[1])])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should test here with the actual 'C0', .. instead of with the converted to hex colors ?

for c in colors:
_check_plot_works(df.plot, color=hex_color[int(c[1])])
with tm.assertRaises(ValueError):
df.plot(color='')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this in a separate test? (just give it another name, it is not really related to mpl2)

@GuessWhoSamFoo
Copy link
Contributor Author

Fixed test and figured out how to test only for matplotlib >= 2.0.0

The test for color='' does not include a case in a list (e.g. color=['r'ed, '') because matplotlib will throw the error when trying to convert to_rgba.

There seems to be no remaining cases where a string passed as a color can also be parsed as an additional color outside of C[0-9] since the other color cycle is bgrcmyk. It could be possible by defining a custom color cycle but not obvious on how to accomplish this.

https://github.com/GuessWhoSamFoo/pandas/blob/str_color_cycle/pandas/tools/plotting.py#L236-L239

@TomAugspurger TomAugspurger merged commit 7b8a6b1 into pandas-dev:master Apr 12, 2017
@TomAugspurger
Copy link
Contributor

@GuessWhoSamFoo thanks!

@GuessWhoSamFoo GuessWhoSamFoo deleted the str_color_cycle branch April 13, 2017 20:11
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 this pull request may close these issues.

VIS: plot method cannot handle new 'C0'-like colors (matplotlib 2.0)
4 participants