Hist2D with matplotlib

3,794 views
Skip to first unread message

revkarol

unread,
May 3, 2013, 10:24:25 AM5/3/13
to rootpy...@googlegroups.com
Hi,

1. Is this the official place to ask questions on rootpy or is there another forum that's more commonly used?

2. Could you give an example of out to plot a 2d histogram with rootpy with say the "COLZ" option?

Advance thanks,
Karol.

Joseph McCartin

unread,
May 3, 2013, 11:26:07 AM5/3/13
to rootpy...@googlegroups.com
Hi,

I've also been getting acquainted with the rootpy API recently, and I have found that the examples on the API reference pages help, especially since the documentation has large parts missing.  See this example: http://rootpy.org/auto_examples/plotting/plot_matplotlib_hist.html It would be nicer if people posted more examples there however!  

If you're familiar with pyroot, the drawing and filling of histograms are mostly done with the same syntax.  I do often run into trouble with initialisation (in particular, I still have to revert back to pyroot for TGraphs), but sometimes searching though the source with grep or this can help with the syntax you'll need.  Do you have any specific problems with filling of histograms, or are you just starting out?

Cheers,
Joseph


--
You received this message because you are subscribed to the Google Groups "rootpy users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rootpy-users...@googlegroups.com.
To post to this group, send email to rootpy...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/rootpy-users/-/kBywe8sM1xkJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

revkarol

unread,
May 3, 2013, 11:37:01 AM5/3/13
to rootpy...@googlegroups.com
Hi,

I've scoured the documentation quite a bit.  The 1D histogram plots fine, but I can't plot a 2D histogram using the rootpy.plotting.root2matplotlib module.  Maybe 2D is not supported yet?  Or maybe I'm just missing some flag.  I basically want the 2D version of the example you gave.

Karol.

Peter Waller

unread,
May 5, 2013, 7:04:12 AM5/5/13
to rootpy...@googlegroups.com
Hi, apologies for the slow response, things have been busy.

I think the resource you're looking for is matplotlib's gallery [1].

If you skim through root2matplotlib [2], I see nothing resembling helpers which make calls to pylab's hist2d or matplotlib's contour, etc. Therefore at the moment it looks like your best bet is to use matplotlib directly.

Pull requests are welcome if you want to extend root2matplotlib. Let us know how you get on.




To view this discussion on the web visit https://groups.google.com/d/msg/rootpy-users/-/HNu0cBO9gv0J.

Noel Dawe

unread,
May 5, 2013, 1:25:31 PM5/5/13
to rootpy...@googlegroups.com
Hi Karol,

I also apologise for my slow response for the same reason.

We have not implemented helper functions to draw 2d histograms, but I managed to get this working:

from matplotlib import pyplot as plt
from rootpy.plotting import Hist2D
import numpy as np

a = Hist2D(100, -3, 3, 100, -3, 3)
a.fill_array(np.random.randn(1000000, 2))

X, Y = np.meshgrid(list(a.x()), list(a.y()))
x = X.ravel()
y = Y.ravel()
z = np.array(a.z()).ravel()

plt.hist2d(x, y, weights=z, bins=(list(a.xedges()), list(a.yedges())))
"""
plt.imshow(a.z(),
           extent=[a.xedges(0), a.xedges(-1),
                   a.yedges(0), a.xedges(-1)],
           interpolation='nearest')
"""
plt.colorbar()
plt.show()

So there are two options: use imshow() or hist2d(). We are debugging an issue with ROOT's GUI not playing nice with matplotlib's so you might see a segmentation fault if you use both GUIs together interactively:


Cheers,
Noel


Vancouver: +1 778 373 9738
Geneva: +41 76 631 44 50 (cell)
Skype: noel.dawe

revkarol

unread,
May 6, 2013, 6:06:47 AM5/6/13
to rootpy...@googlegroups.com
Thanks Noel, that's just about there.

My version of matplotlib is a bit old so I don't have plt.hist2d (must have been added in v1.2...).  I can use imshow though, with one minor change.  The x and y are transposed for me, so I zip, and also need to set the aspect to auto:

az = a.z()
plt.imshow(zip(*az),
           extent=[a.xedges(0), a.xedges(-1),
                   a.yedges(0), a.xedges(-1)],
           aspect = 'auto',
           interpolation='nearest')

Karol.

Noel Dawe

unread,
May 6, 2013, 10:46:56 AM5/6/13
to rootpy...@googlegroups.com
Hi Karol,

Great, and if you want to keep the transpose operation on the numpy side you can add a ".T" to the end of "np.array(a.z())". I also had a typo in the extent= argument:

from matplotlib import pyplot as plt
from rootpy.plotting import Hist2D
import numpy as np

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=(1E6,)))

X, Y = np.meshgrid(list(a.x()), list(a.y()))
x = X.ravel()
y = Y.ravel()
z = np.array(a.z()).T

#plt.hist2d(x, y, weights=z.ravel(), bins=(list(a.xedges()), list(a.yedges())))
plt.imshow(z,
           extent=[a.xedges(0), a.xedges(-1),
                   a.yedges(0), a.yedges(-1)],
           interpolation='nearest',
           aspect='auto')

plt.colorbar()
plt.show()

Cheers,
Noel

Vancouver: +1 778 373 9738
Geneva: +41 76 631 44 50 (cell)
Skype: noel.dawe


To view this discussion on the web visit https://groups.google.com/d/msg/rootpy-users/-/KT5PAuysxK8J.

Noel Dawe

unread,
May 6, 2013, 11:01:59 PM5/6/13
to rootpy...@googlegroups.com, revk...@gmail.com
You should also add origin='lower' in imshow() to make the lower left the origin instead of the upper left. Another issue with imshow is that it cannot support variable width binning. You will need hist2d for that.

Here is my final script:

from matplotlib import pyplot as plt
from rootpy.plotting import Hist2D
import numpy as np

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=(1E6,)))

X, Y = np.meshgrid(list(a.x()), list(a.y()))
x = X.ravel()
y = Y.ravel()
z = np.array(a.z()).T

fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
ax1 = plt.subplot(1,2,1)
ax1.set_title("hist2d")
ax1.hist2d(x, y, weights=z.ravel(), bins=(list(a.xedges()), list(a.yedges())))
ax2 = plt.subplot(1,2,2)
ax2.set_title('imshow')
im = ax2.imshow(z,
    extent=[a.xedges(0), a.xedges(-1),
            a.yedges(0), a.yedges(-1)],
    interpolation='nearest',
    aspect='auto',
    origin='lower')

fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)
fig.savefig('hist2d.png')
plt.show()

and the output:

Inline image 1

I'll soon submit a rootpy PR adding 2D helper functions, now that I know how they should be implemented!

Cheers,
Noel

Vancouver: +1 778 373 9738
Geneva: +41 76 631 44 50 (cell)
Skype: noel.dawe


hist2d.png

Noel Dawe

unread,
Jun 12, 2013, 4:00:50 AM6/12/13
to rootpy...@googlegroups.com, revk...@gmail.com
rootpy now has new functions for plotting 2D histograms with matplotlib as of this PR:
hist2d.png

revkarol

unread,
Jun 24, 2013, 10:40:57 AM6/24/13
to rootpy...@googlegroups.com
That works nicely Noel.  Thanks.
Reply all
Reply to author
Forward
0 new messages