On 2014/04/24 11:40 PM, Tom Grydeland wrote: > Hi all, > > I will explain what I’m trying to achieve first, then the approaches I’ve > attempted so far, with results. > > I have data on a 2D grid which I want to present as an image — a la > pyplot.imshow() — except that the grid is hexagonal, not rectangular. The > grid can be represented in multiple ways, I use a regular 2D array with the > convention that the lower left hex is (0,0), x increases to the right > (crossing vertical hex boundaries) and y increases upwards slanting to the > right. >
Tom, Have you considered adapting the code from the Axes.hexbin() method? Ideally, the hexbin method might be split into two parts, one for the calculation and another for the plotting. Eric > Ideally, I’d also be able to have a colorbar. > > I’m giving my routines three input vectors: x, y and c. X and y are > initially integers, then transformed to centerpoint coordinates using > x, y = x+.5*y, y*np.cos(np.pi/6) > while c is used to look up values in a colormap. > > I first tried to adapt ‘scatter_demo2.py’ to my needs. Unfortunately, the > pyplot.scatter routine fails when given ‘c’ or ’s’ keywords, as has been > reported elsewhere by somebody else: > > http://stackoverflow.com/questions/20524888/attributeerror-numpy-ndarray-object-has-no-attribute-get-matrix > > I’ve dug around in the code for a bit without finding out how this arises. > It seems to me it has to do with how transforms are being handed around and > at what point their representation is changed from objects to pure matrices. > This backend appears to expect to see objects only, but is handed matrices > instead. I’ve hacked my way around that one in backends/backend_macosx.py by > changing lines around 79-80 from > master_transform = master_transform.get_matrix() > all_transforms = [t.get_matrix() for t in all_transforms] > to > try: > master_transform = master_transform.get_matrix() > except AttributeError: pass > try: > all_transforms = [t.get_matrix() for t in all_transforms] > except AttributeError: pass > (which is a dirty hack, but I don’t know how to do it right) > > Now I can run the scatter_demo2 script, and I can obviously have it produce > hexes at uniform size, but the size of the hexagons are set independently of > the axes. Good for symbols used to mark arbitrary coordinates, not so good > when I try to cover the plane without gaps. > > Next, I’ve tried creating the patches one by one, essentially this: > > r = 1./np.sqrt(3) > for xy, cc in zip(zip(x, y), c): > hexp = mpl.patches.RegularPolygon(xy, 6, radius=r, facecolor=cc, > edgecolor=’none') > ax.add_patch(hexp) > ax.autoscale_view() > ax.figure.canvas.draw() > > This works as I want it to, but becomes unbearably slow when the number of > hexes grows beyond a few thousand. > > Given that RegularPolygon can do the trick, it seems likely that > RegularPolyCollection should also be able to? > > This is what I tried: > > ax = gca() > collection = RegularPolyCollection( > 6, # a pentagon > rotation=(np.pi/7,), > sizes=(.5/np.sqrt(3),), > facecolors = cc, > edgecolors = None, > linewidths = (1,), > offsets = zip(xx,yy), > transOffset = ax.transData, > ) > #collection.set_transform(ax.transData) > ax.add_collection(collection, autolim=True) > > ax.autoscale_view() > ax.figure.canvas.draw() > > This produces dots of minute sizes at the desired coordinates. I can tweak > the size to make them bigger, but they don’t scale with the axes, as for the > scatter_demo script used initially. Digging in the docs, I found a reference > to the set_transform() method of Artists, so I tried setting that to > ax.transData (the line commented out in the above snippet), and voila! I have > hexagons covering the plane again. Strangely enough, they’re not in the > right place anymore (and the locations change when zooming in or out), the > sizes aren’t _quite_ right, the autoscaling of axes appear to believe the > patches are where I wanted them to be, not where they appear on the plot, > results are very different if saving to a figure instead of drawing to a > figure window, etc. > > Is there a way I can make RegularPolyCollection patches transform with axes > coordinates in the same way that RegularPolygon patches do? > > Am I barking up the wrong tree, is there another, blindingly obvious, way I > should be doing this? > > The observant reader will also notice the strange rotation keyword given to > RegularPolyCollection. This keyword is ignored in the macosx backend, and I > have been unable to find out why. > > Thank you for all tips and pointers > > --Tom Grydeland > > > ------------------------------------------------------------------------------ > Start Your Social Network Today - Download eXo Platform > Build your Enterprise Intranet with eXo Platform Software > Java Based Open Source Intranet - Social, Extensible, Cloud Ready > Get Started Now And Turn Your Intranet Into A Collaboration Platform > http://p.sf.net/sfu/ExoPlatform > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > ------------------------------------------------------------------------------ Start Your Social Network Today - Download eXo Platform Build your Enterprise Intranet with eXo Platform Software Java Based Open Source Intranet - Social, Extensible, Cloud Ready Get Started Now And Turn Your Intranet Into A Collaboration Platform http://p.sf.net/sfu/ExoPlatform _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users