## Re: [Matplotlib-users] Combining pcolormesh and contour

 Re: [Matplotlib-users] Combining pcolormesh and contour From: Andreas H. - 2012-02-28 19:41:37 ```Am Di 28 Feb 2012 19:23:14 CET schrieb Eric Firing: > On 02/28/2012 08:08 AM, Andreas H. wrote: >> Am 28.02.2012 18:56, schrieb Eric Firing: >>> On 02/28/2012 06:28 AM, Andreas H. wrote: >>>>>> On Tuesday, February 28, 2012, Andreas H. wrote: >>>>>> >>>>>>> Good morning, >>>>>>> >>>>>>> I'm creating the attached plot using pcolormesh(). What I would like to >>>>>>> do now is draw contour lines at +/- 2.5%, which follow the grid edges. >>>>>>> >>>>>>> The problem is that when I use contour(), the lines drawn do not follow >>>>>>> the grid edges but seem to be interpolated somehow. >>>>>>> >>>>>>> Do you have an idea how to draw the contour lines following the grid >>>>>>> edges? >>>>>>> >>>>>>> Your insight is very much appreciated :) >>>>>>> >>>>>>> Cheers, >>>>>>> Andreas. >>>>>>> >>>>>> >>>>>> This is because of a subtle difference in how pcolor-like functions and >>>>>> contour-like functions work. I always forget which is which, but one >>>>>> assumes that the z value lies on the vertices of the grid while the >>>>>> other >>>>>> assumes that it lies in the middle of each grid point. This is why you >>>>>> see >>>>>> them slightly offset from each other. >>>>> >>>>> Thanks, Ben! >>>>> >>>>> To `pcolormesh`, I pass the *edges* of the grid: >>>>> >>>>> xbin = linspace(0, 12, nxbin + 1) >>>>> ybin = np.linspace(-90, 90, nybin + 1) >>>>> >>>>> pl = spl.pcolormesh(xbin, ybin, pdata.T, cmap=cmap, edgecolors='None', >>>>> vmin=-5, vmax=20) >>>>> >>>>> `contour`, however, wants the coordinates themselves. So I do >>>>> >>>>> spl.contour((xbin[:-1]+xbin[1:])/2., (ybin[:-1]+ybin[1:])/2, pdata.T, >>>>> [-2.5, 2.5]) >>>>> >>>>> Still, the outcome is, well, unexpected to me. Actually, no matter if >>>>> contour wants centres or edges, the actual behaviour seems strange. There >>>>> is some interpolation going on, apparently. The input `pdata` has shape >>>>> (12, 72) (or 72,12), and I definitely wouldn't expect this sub-grid >>>>> movement in the x-direction. >>>>> >>>>> Any ideas? >>>> >>>> Okay, after some diving into matplotlib sources, I guess the interpolation >>>> comes within the function `QuadContourSet._get_allsegs_and_allkinds`. So >>>> there seems to be no way to accomplish what I actually want with the >>>> current matplotlib API. Correct? >>>> >>>> If I wanted to do something about this, I would need to >>>> >>>> * implement a class `GriddedContourSet`, derived from `ContourSet`, where >>>> I implement the `_get_allsegs_and_allkinds` method appropriately. >>>> * add an additional keyword argument to `contour()` to make this gridded >>>> contourset an option when calling `contour()`. >>>> >>>> Is this all correct? If yes, I might start working on this if I get the >>>> time ... >>> >>> It is not at all clear to me what you want to do, as compared to what >>> contour does. Can you illustrate with an extremely simple example? >>> Maybe even a scanned sketch, if necessary? Do you want the contour lines >>> to be stepped, like the rectilinear boundaries of the pcolormesh >>> cells--that is, composed entirely of horizontal and vertical line segments? >> >> Yes, Eric, that's exactly what I want. Since my case was simple enough, >> I did it completely manually, with loads of calls to `plot` (I'm sure >> there would've been a simpler solution ... -- which one?). I attached >> the plot so you get an idea of what I want to do. > > Andreas, > > I have never seen a contour algorithm with an option to do that, but I > understand the motivation. I don't think it would be easy to implement; > contouring algorithms generally are not. > > You might get an adequate approximation by using nearest-neighbor > interpolation to interpolate your data to a very fine grid, and then > contour that. Eric, thanks, that's a good hint. I took a look into the C source of the contour algorithm and decided not to bother right now. But your suggestion should do it. Cheers, Andreas. ```