Repository: holoviz/hvplot

Issue:
Line plot should ignore non-numeric column
I got this example:
```python
df = pandas.DataFrame({'foo': [1, 2, 3, 4],
                       'bar': [3, 1, 4, 2],
                       'label': list('xyzh')},
                      index=list('abcd'))
df.hvplot(kind='line')
```

Which is generating the next plot:

![hvplot_line](https://user-images.githubusercontent.com/10058240/61065917-85991900-a3fc-11e9-931b-4762f871c523.png)

Not sure about other cases, but I think in this case it'd make sense to ignore the `label` column, instead of adding its values to the y axis. That's what the pandas matplotlib backend does.


Discussion:
One way to generalize this is that when data are plotted on the same axis they should all either be numeric or non-numeric.
>One way to generalize this is that when data are plotted on the same axis they should all either be numeric or non-numeric.

I agree with this, line plots on categorical axes are weird but I think it's fine not to be prescriptive here. Unless a non-numeric columns is explicitly specified numeric columns should take precedence though.

Resolving patch:
diff --git a/hvplot/converter.py b/hvplot/converter.py
--- a/hvplot/converter.py
+++ b/hvplot/converter.py
@@ -919,6 +919,12 @@ def _process_args(self, data, x, y):
         y = y or self.y
         if not y:
             ys = [c for c in data.columns if c not in [x]+self.by+self.groupby]
+            if len(ys) > 1:
+                # if columns have different dtypes, only include numeric columns
+                from pandas.api.types import is_numeric_dtype as isnum
+                num_ys = [col for col in data.columns if isnum(data[col])]
+                if len(num_ys) >= 1:
+                    ys = num_ys
             y = ys[0] if len(ys) == 1 else ys
         return data, x, y
 


Test patch:
diff --git a/hvplot/tests/testcharts.py b/hvplot/tests/testcharts.py
--- a/hvplot/tests/testcharts.py
+++ b/hvplot/tests/testcharts.py
@@ -36,9 +36,9 @@ def test_heatmap_2d_index_columns(self):
         plot = self.df.hvplot.heatmap()
         self.assertEqual(plot, HeatMap((['x', 'y'], [0, 1, 2], self.df.values),
                                        ['columns', 'index'], 'value'))
-        
 
-        
+
+
 class TestChart1D(ComparisonTestCase):
 
     def setUp(self):
@@ -50,6 +50,8 @@ def setUp(self):
         self.df = pd.DataFrame([[1, 2], [3, 4], [5, 6]], columns=['x', 'y'])
         self.cat_df = pd.DataFrame([[1, 2, 'A'], [3, 4, 'B'], [5, 6, 'C']],
                                    columns=['x', 'y', 'category'])
+        self.cat_only_df = pd.DataFrame([['A', 'a'], ['B', 'b'], ['C', 'c']],
+                                        columns=['upper', 'lower'])
 
     @parameterized.expand([('line', Curve), ('area', Area), ('scatter', Scatter)])
     def test_wide_chart(self, kind, element):
@@ -134,3 +136,32 @@ def test_histogram_legend_position(self):
         plot = self.cat_df.hvplot.hist('y', legend='left')
         opts = Store.lookup_options('bokeh', plot, 'plot')
         self.assertEqual(opts.kwargs['legend_position'], 'left')
+
+    @parameterized.expand([('line', Curve), ('area', Area), ('scatter', Scatter)])
+    def test_only_includes_num_chart(self, kind, element):
+        plot = self.cat_df.hvplot(kind=kind)
+        obj = NdOverlay({'x': element(self.cat_df, 'index', 'x').redim(x='value'),
+                         'y': element(self.cat_df, 'index', 'y').redim(y='value'),
+                        }, 'Variable')
+        self.assertEqual(plot, obj)
+
+    @parameterized.expand([('line', Curve), ('area', Area), ('scatter', Scatter)])
+    def test_includes_str_if_no_num_chart(self, kind, element):
+        plot = self.cat_only_df.hvplot(kind=kind)
+        obj = NdOverlay({'upper': element(self.cat_only_df, 'index', 'upper').redim(upper='value'),
+                         'lower': element(self.cat_only_df, 'index', 'lower').redim(lower='value'),
+                        }, 'Variable')
+        self.assertEqual(plot, obj)
+
+class TestChart1DDask(TestChart1D):
+
+    def setUp(self):
+        super().setUp()
+        try:
+            import dask.dataframe as dd
+        except:
+            raise SkipTest('Dask not available')
+        patch('dask')
+        self.df = dd.from_pandas(self.df, npartitions=2)
+        self.cat_df = dd.from_pandas(self.cat_df, npartitions=3)
+        self.cat_only_df = dd.from_pandas(self.cat_only_df, npartitions=1)