Repository: pandas-dev/pandas

Issue:
pandas.plotting.parallel_coordinates resets random seed!
#### Code Sample, a copy-pastable example if possible

```
>>> x = pd.DataFrame(np.zeros((10,10)))
>>> x
     0    1    2    3    4    5    6    7    8    9
0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
1  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
2  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
3  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
4  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
5  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
6  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
7  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
8  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
9  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
>>> pandas.plotting.parallel_coordinates(x,0)
<matplotlib.axes._subplots.AxesSubplot object at 0x10b6b11d0>
>>> random.random()
0.25891675029296335
>>> pandas.plotting.parallel_coordinates(x,0)
<matplotlib.axes._subplots.AxesSubplot object at 0x10b6b11d0>
>>> random.random()
0.25891675029296335


```
#### Problem description

A call to the pandas.plotting.parallel_coordinates method resets the random seed

#### Expected Output

#### Output of ``pd.show_versions()``

<details>

[paste the output of ``pd.show_versions()`` here below this line]
INSTALLED VERSIONS
------------------
commit: None
python: 2.7.13.final.0
python-bits: 64
OS: Darwin
OS-release: 16.7.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: None.None

pandas: 0.20.3
pytest: 3.2.1
pip: 9.0.1
setuptools: 36.2.7
Cython: 0.26
numpy: 1.13.1
scipy: 0.19.1
xarray: None
IPython: 5.3.0
sphinx: 1.6.3
patsy: 0.4.1
dateutil: 2.6.1
pytz: 2017.2
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: 2.0.2
openpyxl: None
xlrd: 1.0.0
xlwt: None
xlsxwriter: None
lxml: None
bs4: 4.6.0
html5lib: 0.999999999
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.9.6
s3fs: None
pandas_gbq: None
pandas_datareader: None
</details>


Discussion:
Checked it on another computer and it resets to the *same* random seed, yielding the same output from random.random()

Here is the version info for that computer:
INSTALLED VERSIONS
------------------
commit: None
python: 2.7.7.final.0
python-bits: 64
OS: Linux
OS-release: 2.6.32-431.el6.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: None.None

pandas: 0.19.2
nose: 1.3.7
pip: 9.0.1
setuptools: 28.8.0
Cython: 0.25.2
numpy: 1.12.1
scipy: 0.19.0
statsmodels: None
xarray: None
IPython: 5.3.0
sphinx: 1.5.3
patsy: 0.4.1
dateutil: 2.6.0
pytz: 2017.2
blosc: None
bottleneck: 1.2.0
tables: 3.3.0
numexpr: 2.6.2
matplotlib: 2.0.0
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: 0.999999999
httplib2: None
apiclient: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.9.5
boto: None
pandas_datareader: None
Thanks for the bug report. Looks like the issue is at https://github.com/pandas-dev/pandas/blob/f11bbf2f505d81900cc83ce387a6a1b1d2a2f866/pandas/plotting/_style.py#L113-L120

Could you submit a fix @jasonzutty?
I'll take a crack at it, just remove the seed?
Maybe a numpy RandomContext, to get reproducible colors? I haven't looked closely. 

Resolving patch:
diff --git a/pandas/plotting/_style.py b/pandas/plotting/_style.py
--- a/pandas/plotting/_style.py
+++ b/pandas/plotting/_style.py
@@ -9,7 +9,7 @@
 import numpy as np
 
 from pandas.core.dtypes.common import is_list_like
-from pandas.compat import range, lrange, lmap
+from pandas.compat import lrange, lmap
 import pandas.compat as compat
 from pandas.plotting._compat import _mpl_ge_2_0_0
 
@@ -111,11 +111,13 @@ def _get_standard_colors(num_colors=None, colormap=None, color_type='default',
             if isinstance(colors, compat.string_types):
                 colors = list(colors)
         elif color_type == 'random':
-            import random
+            from pandas.core.common import _random_state
 
             def random_color(column):
-                random.seed(column)
-                return [random.random() for _ in range(3)]
+                """ Returns a random color represented as a list of length 3"""
+                # GH17525 use common._random_state to avoid resetting the seed
+                rs = _random_state(column)
+                return rs.rand(3).tolist()
 
             colors = lmap(random_color, lrange(num_colors))
         else:


Test patch:
diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py
--- a/pandas/tests/plotting/test_misc.py
+++ b/pandas/tests/plotting/test_misc.py
@@ -284,3 +284,20 @@ def test_subplot_titles(self):
                                                   title=title[:-1])
         title_list = [ax.get_title() for sublist in plot for ax in sublist]
         assert title_list == title[:3] + ['']
+
+    def test_get_standard_colors_random_seed(self):
+        # GH17525
+        df = DataFrame(np.zeros((10, 10)))
+
+        # Make sure that the random seed isn't reset by _get_standard_colors
+        plotting.parallel_coordinates(df, 0)
+        rand1 = random.random()
+        plotting.parallel_coordinates(df, 0)
+        rand2 = random.random()
+        assert rand1 != rand2
+
+        # Make sure it produces the same colors every time it's called
+        from pandas.plotting._style import _get_standard_colors
+        color1 = _get_standard_colors(1, color_type='random')
+        color2 = _get_standard_colors(1, color_type='random')
+        assert color1 == color2