Repository: GenericMappingTools/pygmt

Issue:
Histogram doesn't work for pandas.Series
**Description of the problem**

<!-- Please be as detailed as you can when describing an issue. The more information we have, the easier it will be for us to track this down. -->

**Full code that generated the error**

```python
import pygmt
import pandas as pd
import numpy as np

table = pd.read_csv("https://raw.githubusercontent.com/GenericMappingTools/pygmt/master/pygmt/tests/data/points.txt", sep=" ", header=None)

fig = pygmt.Figure()
fig.histogram(table[0], pen="1p", series=[0, 90, 10], frame=True)             # Fail
#fig.histogram(np.array(table[0]), pen="1p", series=[0, 90, 10], frame=True)  # Pass
fig.show()
```
I have to convert `table[0]` to a numpy array to make it work.

**Full error message**

```
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    fig.histogram(table[0], pen="1p", series=[0, 90, 10], frame=True)
  File "pygmt/pygmt/helpers/decorators.py", line 297, in new_module
    return module_func(*args, **kwargs)
  File "pygmt/pygmt/helpers/decorators.py", line 438, in new_module
    return module_func(*args, **kwargs)
  File "pygmt/pygmt/src/histogram.py", line 57, in histogram
    with file_context as infile:
  File "lib/python3.8/contextlib.py", line 113, in __enter__
    return next(self.gen)
  File "pygmt/pygmt/clib/session.py", line 1159, in virtualfile_from_vectors
    rows = len(arrays[0])
TypeError: len() of unsized object
```

**System information**

Please paste the output of `python -c "import pygmt; pygmt.show_versions()"`:

```
PyGMT information:
  version: v0.3.2.dev82+g82ebbbc4.d20210412
System information:
  python: 3.8.5 (default, Sep  4 2020, 02:22:02)  [Clang 10.0.0 ]
  executable: /Users/XXX/.miniconda/bin/python
  machine: macOS-10.16-x86_64-i386-64bit
Dependency information:
  numpy: 1.20.1
  pandas: 1.2.3
  xarray: 0.17.0
  netCDF4: 1.5.6
  packaging: 20.9
  ghostscript: 9.53.3
  gmt: 6.2.0_522a350_2021.04.29
GMT library information:
  binary dir: /Users/XXX/.miniconda/bin
  cores: 8
  grid layout: rows
  library path: /Users/XXX/opt/GMT-master/lib/libgmt.dylib
  padding: 2
  plugin dir: /Users/XXX/opt/GMT-master/lib/gmt/plugins
  share dir: /Users/XXX/opt/GMT-master/share
  version: 6.2.0
```


Discussion:

Patch:
diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py
index 8172dbdb..89026a71 100644
--- a/pygmt/clib/session.py
+++ b/pygmt/clib/session.py
@@ -1449,9 +1449,11 @@ class Session:
                 _data.extend(extra_arrays)
         elif kind == "matrix":  # turn 2D arrays into list of vectors
             try:
+                # pandas.Series will be handled below like a 1d numpy ndarray
+                assert not hasattr(data, "to_frame")
                 # pandas.DataFrame and xarray.Dataset types
                 _data = [array for _, array in data.items()]
-            except AttributeError:
+            except (AttributeError, AssertionError):
                 try:
                     # Just use virtualfile_from_matrix for 2D numpy.ndarray
                     # which are signed integer (i), unsigned integer (u) or
@@ -1460,7 +1462,7 @@ class Session:
                     _virtualfile_from = self.virtualfile_from_matrix
                     _data = (data,)
                 except (AssertionError, AttributeError):
-                    # Python lists, tuples, and numpy ndarray types
+                    # Python list, tuple, numpy ndarray and pandas.Series types
                     _data = np.atleast_2d(np.asanyarray(data).T)
 
         # Finally create the virtualfile from the data, to be passed into GMT


Test patch:
diff --git a/pygmt/tests/test_histogram.py b/pygmt/tests/test_histogram.py
index 77dd5f03..eb9a3828 100644
--- a/pygmt/tests/test_histogram.py
+++ b/pygmt/tests/test_histogram.py
@@ -2,22 +2,24 @@
 """
 Tests histogram.
 """
+import pandas as pd
 import pytest
 from pygmt import Figure
 
 
-@pytest.fixture(scope="module")
-def table():
+@pytest.fixture(scope="module", name="table", params=[list, pd.Series])
+def fixture_table(request):
     """
     Returns a list of integers to be used in the histogram.
     """
-    return [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8]
+    data = [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8]
+    return request.param(data)
 
 
-@pytest.mark.mpl_image_compare
+@pytest.mark.mpl_image_compare(filename="test_histogram.png")
 def test_histogram(table):
     """
-    Tests plotting a histogram using a list of integers.
+    Tests plotting a histogram using a sequence of integers from a table.
     """
     fig = Figure()
     fig.histogram(
diff --git a/pygmt/tests/test_info.py b/pygmt/tests/test_info.py
index b3a0b4ae..b364a33b 100644
--- a/pygmt/tests/test_info.py
+++ b/pygmt/tests/test_info.py
@@ -38,6 +38,15 @@ def test_info_2d_list():
     assert output == expected_output
 
 
+def test_info_series():
+    """
+    Make sure info works on a pandas.Series input.
+    """
+    output = info(pd.Series(data=[0, 4, 2, 8, 6]))
+    expected_output = "<vector memory>: N = 5 <0/8>\n"
+    assert output == expected_output
+
+
 def test_info_dataframe():
     """
     Make sure info works on pandas.DataFrame inputs.