Repository: rootpy/rootpy

Issue:
rootpy.Graph not working with rootpy.plotting.root2matplotlib.errorbar (again)
Pretty much the same issue as #289, although the traceback is now different:

```
Traceback (most recent call last):
  File "rootpy_graph_bug_example.py", line 19, in <module>
    rootpy_graph = Graph(hist = rootpy_hist)
  File "~/DailyPythonScripts/external/rootpy/rootpy/plotting/graph.py", line 624, in __new__
    *args, **kwargs)
TypeError: __init__() takes at least 2 arguments (1 given)
```

Seems to be broken with ROOT.TGraphAsymmErrors, too, giving the following error:

```
Traceback (most recent call last):
  File "rootpy_graph_bug_example.py", line 34, in <module>
    rplt.errorbar(rootpy_graph, axes=axes)
  File "~/DailyPythonScripts/external/rootpy/rootpy/plotting/root2matplotlib.py", line 430, in errorbar
    **kwargs)
  File "~/DailyPythonScripts/external/rootpy/rootpy/plotting/root2matplotlib.py", line 430, in errorbar
    **kwargs)
  File "~/DailyPythonScripts/external/rootpy/rootpy/plotting/root2matplotlib.py", line 422, in errorbar
    for h in hists:
TypeError: 'float' object is not iterable
```

Is it a bug, or a feature?



Discussion:
@senkin I'm fixing this now. Thanks for reporting!

Regarding the first part. Graph now accepts one positional argument that is either a number of points or a histogram, so instead do this:

``` python
>>> from rootpy.plotting import Hist, Graph
>>> h = Hist(100, -5, 5)
>>> h.FillRandom('gaus')
>>> g = Graph(h)
>>> g.Draw()
```

I finally added unit tests for root2matplotlib so regressions like this should not happen again.

should be all fixed in #456 

Thanks a lot!


Resolving patch:
diff --git a/rootpy/plotting/root2matplotlib.py b/rootpy/plotting/root2matplotlib.py
--- a/rootpy/plotting/root2matplotlib.py
+++ b/rootpy/plotting/root2matplotlib.py
@@ -10,8 +10,8 @@
 import matplotlib.pyplot as plt
 import numpy as np
 
-from .hist import _HistBase
-from .graph import Graph
+from .hist import _Hist
+from .graph import _Graph1DBase
 from .utils import get_limits
 
 
@@ -157,7 +157,7 @@ def hist(hists, stacked=True, reverse=False, axes=None,
     curr_ylim = axes.get_ylim()
     was_empty = not axes.has_data()
     returns = []
-    if isinstance(hists, _HistBase) or isinstance(hists, Graph):
+    if isinstance(hists, _Hist):
         # This is a single plottable object.
         returns = _hist(hists, axes=axes, logy=logy, **kwargs)
         _set_bounds(hists, axes=axes,
@@ -253,10 +253,9 @@ def bar(hists, stacked=True, reverse=False,
     """
     Make a matplotlib bar plot.
 
-    *hists* may be a single :class:`rootpy.plotting.hist.Hist`, a single
-    :class:`rootpy.plotting.graph.Graph`, a list of either type, or a
-    :class:`rootpy.plotting.hist.HistStack`.  All additional keyword
-    arguments will be passed to :func:`matplotlib.pyplot.bar`.
+    *hists* may be a single :class:`rootpy.plotting.Hist`, a list of
+    histograms, or a :class:`rootpy.plotting.HistStack`.  All additional
+    keyword arguments will be passed to :func:`matplotlib.pyplot.bar`.
 
     Keyword arguments:
 
@@ -288,7 +287,7 @@ def bar(hists, stacked=True, reverse=False,
     logy = kwargs.pop('log', axes.get_yscale() == 'log')
     kwargs['log'] = logy
     returns = []
-    if isinstance(hists, _HistBase):
+    if isinstance(hists, _Hist):
         # This is a single histogram.
         returns = _bar(hists, xerr=xerr, yerr=yerr,
                        axes=axes, **kwargs)
@@ -406,7 +405,7 @@ def errorbar(hists, xerr=True, yerr=True, axes=None,
     curr_ylim = axes.get_ylim()
     was_empty = not axes.has_data()
     returns = []
-    if isinstance(hists, _HistBase) or isinstance(hists, Graph):
+    if isinstance(hists, (_Hist, _Graph1DBase)):
         # This is a single plottable object.
         returns = _errorbar(
             hists, xerr, yerr,
diff --git a/rootpy/plotting/utils.py b/rootpy/plotting/utils.py
--- a/rootpy/plotting/utils.py
+++ b/rootpy/plotting/utils.py
@@ -6,8 +6,8 @@
 
 import ROOT
 
-from .hist import _HistBase, HistStack
-from .graph import Graph
+from .hist import _Hist, HistStack
+from .graph import _Graph1DBase, Graph
 
 __all__ = [
     'get_limits',
@@ -72,14 +72,14 @@ def get_limits(h,
                logx=False,
                logy=False):
     """
-    Get the axes limits that should be used for a histogram or graph
+    Get the axes limits that should be used for a 1D histogram or graph
     """
     import numpy as np
 
     if isinstance(h, HistStack):
         h = h.sum
 
-    if isinstance(h, (_HistBase, Graph)):
+    if isinstance(h, (_Hist, _Graph1DBase)):
         y_array_min = y_array_max = np.array(list(h.y()))
         if yerror_in_padding:
             y_array_min = y_array_min - np.array(list(h.yerrl()))
@@ -88,7 +88,7 @@ def get_limits(h,
             y_array_min = y_array_min[y_array_min > 0]
         ymin = y_array_min.min()
         ymax = y_array_max.max()
-        if isinstance(h, Graph):
+        if isinstance(h, _Graph1DBase):
             x_array_min = x_array_max = np.array(list(h.x()))
             if xerror_in_padding:
                 x_array_min = x_array_min - np.array(list(h.xerrl()))


Test patch:
diff --git a/rootpy/plotting/tests/test_root2matplotlib.py b/rootpy/plotting/tests/test_root2matplotlib.py
new file mode 100644
--- /dev/null
+++ b/rootpy/plotting/tests/test_root2matplotlib.py
@@ -0,0 +1,86 @@
+# Copyright 2012 the rootpy developers
+# distributed under the terms of the GNU General Public License
+from rootpy.plotting import Hist, Hist2D, Graph
+from nose.plugins.skip import SkipTest
+
+
+def test_errorbar():
+    try:
+        from rootpy.plotting import root2matplotlib as rplt
+    except ImportError:
+        raise SkipTest
+    h = Hist(100, -5, 5)
+    h.FillRandom('gaus')
+    g = Graph(h)
+    rplt.errorbar(g)
+    rplt.errorbar(h)
+
+
+def test_bar():
+    try:
+        from rootpy.plotting import root2matplotlib as rplt
+    except ImportError:
+        raise SkipTest
+    h = Hist(100, -5, 5)
+    h.FillRandom('gaus')
+    rplt.bar(h)
+
+
+def test_hist():
+    try:
+        from rootpy.plotting import root2matplotlib as rplt
+    except ImportError:
+        raise SkipTest
+    h = Hist(100, -5, 5)
+    h.FillRandom('gaus')
+    rplt.hist(h)
+
+
+def test_hist2d():
+    try:
+        from rootpy.plotting import root2matplotlib as rplt
+        from matplotlib import pyplot
+        import numpy as np
+    except ImportError:
+        raise SkipTest
+    if not hasattr(pyplot, 'hist2d'):
+        raise SkipTest
+    a = Hist2D(100, -3, 3, 100, 0, 6)
+    a.fill_array(np.random.multivariate_normal(
+        mean=(0, 3),
+        cov=np.arange(4).reshape(2, 2),
+        size=(1E3,)))
+    rplt.hist2d(a)
+
+
+def test_imshow():
+    try:
+        from rootpy.plotting import root2matplotlib as rplt
+        import numpy as np
+    except ImportError:
+        raise SkipTest
+    a = Hist2D(100, -3, 3, 100, 0, 6)
+    a.fill_array(np.random.multivariate_normal(
+        mean=(0, 3),
+        cov=np.arange(4).reshape(2, 2),
+        size=(1E3,)))
+    rplt.imshow(a)
+
+
+def test_contour():
+    try:
+        from rootpy.plotting import root2matplotlib as rplt
+        import numpy as np
+    except ImportError:
+        raise SkipTest
+    a = Hist2D(100, -3, 3, 100, 0, 6)
+    a.fill_array(np.random.multivariate_normal(
+        mean=(0, 3),
+        cov=np.arange(4).reshape(2, 2),
+        size=(1E3,)))
+    rplt.contour(a)
+
+
+if __name__ == "__main__":
+    import nose
+    nose.runmodule()