Combining pcolormesh and contour

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 :slight_smile:

Cheers,
Andreas.

amf-changes_profile.png

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.

I hope that clarifies everything for you.

Ben Root

路路路

On Tuesday, February 28, 2012, Andreas H. wrote:

Good morning,

I鈥檓 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 :slight_smile:

Cheers,

Andreas.

By definitition, with pcolormesh you're giving it the edges of the
grid cells. In fact, for an NxN grid of data, you should have N+1xN+1
grids of x,y values. Contour is given the actual grid and values.

Ryan

路路路

On Tue, Feb 28, 2012 at 9:10 AM, Benjamin Root <ben.root@...1304...> 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 :slight_smile:

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.

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

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?

Cheers,
Andreas.

amf-changes_profile_centre.png

路路路

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 :slight_smile:

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.

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 ...

Cheers,
Andreas.

路路路

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 :slight_smile:

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?

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 :slight_smile:

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?

Eric

路路路

On 02/28/2012 06:28 AM, Andreas H. wrote:

On Tuesday, February 28, 2012, Andreas H. wrote:

Cheers,
Andreas.

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

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.

Thanks for your help!
Andreas.

example.pdf (35.8 KB)

路路路

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 :slight_smile:

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?

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 :slight_smile:

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

路路路

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:

Thanks for your help!
Andreas.

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

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.

路路路

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 :slight_smile:

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.

I think that what you want can be achieved more simply than contouring. I've attached a quick example of how I would do this. I'm assuming that the data has the same form as pcolormesh, i.e, the z values are measured at grid centers but we have coordinate of the edges. This means that we can easily check if a given pixel is above or below the contour level and then we simply draw the appropriate gridlines. I'm not coalescing neighboring lines, but that's also possible.

If you're looking for something more complex than this simple in-or-out partitioning, this approach might still work but I'm not sure, in that case, that I understand what you're actually trying to do.

-Eric

p.s. two loops aren't necessary, really.

lattice_cntr_demo.png

lattice_cntr_demo.py (1.38 KB)

I think that what you want can be achieved more simply than contouring.
I've attached a quick example of how I would do this. I'm assuming that
the data has the same form as pcolormesh, i.e, the z values are measured
at grid centers but we have coordinate of the edges. This means that we
can easily check if a given pixel is above or below the contour level and
then we simply draw the appropriate gridlines. I'm not coalescing
neighboring lines, but that's also possible.

If you're looking for something more complex than this simple in-or-out
partitioning, this approach might still work but I'm not sure, in that
case, that I understand what you're actually trying to do.

Eric, I'm amazed -- thanks a lot :slight_smile:
Andreas.