Repository: pandas-dev/pandas

Issue:
UserWarning about columns and attribute while plotting in Jupyter
#### Code Sample, a copy-pastable example if possible

```python
vibe_df.plot(x='Time', y='Fz')     # This works just fine.
vibe_df.plot(x='Time', y=['Fz'])     # This raises a UserWarning:

```
#### Problem description

I get a UserWarning while plotting a DataFrame.  It only occurs if I pass a list of columns for y.

UserWarning is:
C:\Program Files\Anaconda3\lib\site-packages\pandas\plotting\_core.py:1714: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access
  series.name = label

#### Expected Output
<just the graph>

#### Output of ``pd.show_versions()``
<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.5.4.final.0
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None

pandas: 0.21.0
pytest: 2.9.2
pip: 9.0.1
setuptools: 27.2.0
Cython: 0.24.1
numpy: 1.11.3
scipy: 1.0.0
pyarrow: None
xarray: None
IPython: 6.2.1
sphinx: 1.4.6
patsy: 0.4.1
dateutil: 2.6.0
pytz: 2017.2
blosc: None
bottleneck: 1.1.0
tables: 3.2.2
numexpr: 2.6.4
feather: None
matplotlib: 2.1.0
openpyxl: 2.3.2
xlrd: 1.0.0
xlwt: 1.1.2
xlsxwriter: 0.9.3
lxml: 3.6.4
bs4: 4.5.1
html5lib: None
sqlalchemy: 1.0.13
pymysql: None
psycopg2: None
jinja2: 2.8
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None




Discussion:
This is the line https://github.com/pandas-dev/pandas/blob/fdba133336c2ec8f1269eb15e73d48797840c48b/pandas/plotting/_core.py#L1718

That code pretty clearly assumes that `'y'` is a scalar, and that's how it's documented

```python
Parameters
----------
data : DataFrame
x : label or position, default None
y : label or position, default None
    Allows plotting of one column versus another
```

So we can either validate that `data[y]` is a Series, and raise if not, or see if we can support and document multiple values for `'y'`.

btw, here's a reproducible example

```python
In [12]: df = pd.DataFrame({"A": [1, 2], 'B': [3, 4], 'C': [5, 6]})

In [13]: df.plot(x='A', y=['B', 'C'])
```

Resolving patch:
diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py
--- a/pandas/plotting/_core.py
+++ b/pandas/plotting/_core.py
@@ -19,7 +19,7 @@
     is_number,
     is_hashable,
     is_iterator)
-from pandas.core.dtypes.generic import ABCSeries
+from pandas.core.dtypes.generic import ABCSeries, ABCDataFrame
 
 from pandas.core.common import AbstractMethodError, _try_sort, _any_not_none
 from pandas.core.generic import _shared_docs, _shared_doc_kwargs
@@ -1680,9 +1680,8 @@ def _plot(data, x=None, y=None, subplots=False,
     else:
         raise ValueError("%r is not a valid plot kind" % kind)
 
-    from pandas import DataFrame
     if kind in _dataframe_kinds:
-        if isinstance(data, DataFrame):
+        if isinstance(data, ABCDataFrame):
             plot_obj = klass(data, x=x, y=y, subplots=subplots, ax=ax,
                              kind=kind, **kwds)
         else:
@@ -1690,7 +1689,7 @@ def _plot(data, x=None, y=None, subplots=False,
                              % kind)
 
     elif kind in _series_kinds:
-        if isinstance(data, DataFrame):
+        if isinstance(data, ABCDataFrame):
             if y is None and subplots is False:
                 msg = "{0} requires either y column or 'subplots=True'"
                 raise ValueError(msg.format(kind))
@@ -1702,15 +1701,19 @@ def _plot(data, x=None, y=None, subplots=False,
                 data.index.name = y
         plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
     else:
-        if isinstance(data, DataFrame):
+        if isinstance(data, ABCDataFrame):
             if x is not None:
                 if is_integer(x) and not data.columns.holds_integer():
                     x = data.columns[x]
+                elif not isinstance(data[x], ABCSeries):
+                    raise ValueError("x must be a label or position")
                 data = data.set_index(x)
 
             if y is not None:
                 if is_integer(y) and not data.columns.holds_integer():
                     y = data.columns[y]
+                elif not isinstance(data[y], ABCSeries):
+                    raise ValueError("y must be a label or position")
                 label = kwds['label'] if 'label' in kwds else y
                 series = data[y].copy()  # Don't modify
                 series.name = label


Test patch:
diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py
--- a/pandas/tests/plotting/test_frame.py
+++ b/pandas/tests/plotting/test_frame.py
@@ -2170,6 +2170,26 @@ def test_invalid_kind(self):
         with pytest.raises(ValueError):
             df.plot(kind='aasdf')
 
+    @pytest.mark.parametrize("x,y", [
+        (['B', 'C'], 'A'),
+        ('A', ['B', 'C'])
+    ])
+    def test_invalid_xy_args(self, x, y):
+        # GH 18671
+        df = DataFrame({"A": [1, 2], 'B': [3, 4], 'C': [5, 6]})
+        with pytest.raises(ValueError):
+            df.plot(x=x, y=y)
+
+    @pytest.mark.parametrize("x,y", [
+        ('A', 'B'),
+        ('B', 'A')
+    ])
+    def test_invalid_xy_args_dup_cols(self, x, y):
+        # GH 18671
+        df = DataFrame([[1, 3, 5], [2, 4, 6]], columns=list('AAB'))
+        with pytest.raises(ValueError):
+            df.plot(x=x, y=y)
+
     @pytest.mark.slow
     def test_hexbin_basic(self):
         df = self.hexbin_df