How to split a contourf plot into two sections with different zooms

For example, if I am plotting a vertical section of water temperature from surface to 5000 meters, the portion of the plot from surface to 1000 meters may be too squeezed to show the real story there.
How do I split the contour plots into two panels, with zoomed out portion from surface to 1000 meters, and normal zoom portion from 1000 meters to 5000 meters?
Attached is an example that was plotted using Surfer.

 Accepted Answer

The only builtin non-linear scale is log, but you can roll your own. Here's a simple example:
%%Start with peaks
[x,y,z] = peaks;
%%Two linear equations meeting at y=cutoff
cutoff = 2;
scale = 5;
%%Mask of all Y values above cutoff
above = y>cutoff;
%%Compute scaled Y values
y2 = y;
y2(above) = cutoff + (y(above)-cutoff) * scale;
%%Create contour with y2
contourf(x,y2,z)
%%Fix up tick labels
ax = gca;
yt = ax.YTick;
above = yt>cutoff;
yt(above) = cutoff+(yt(above)-cutoff)/scale;
ax.YTickLabel = yt;
This uses two scales and abruptly switches between them at the cutoff. I've never been very fond of this approach. I think that it's better to use a function with a smooth transition. The basic idea is the same though. You create a scaled copy of your Y coordinates and create the contour with that. Then you fix-up the YTickLabel to be the inverse.
Does that make sense?

6 Comments

Thank you so much. I'm using Matlab R2008 and get the below error:
??? Attempt to reference field of non-structure array.
Error in ==> Untitled at 20
yt = ax.YTick;
??? Attempt to reference field of non-structure array.
Error in ==> Untitled at 20
yt = ax.YTick;
Can we split the two portions physically as if they were two plots? I have attached an example plot that was created by Surfer.
Sorry, the 'dot notation' was added in R2014b. You can replace this:
yt = ax.YTick;
with this:
yt = get(ax,'YTick')
and replace this:
ax.YTickLabel = yt;
with this:
set(ax,'YTickLabel',yt)
Adding a split would be a bit trickier. I would say that the easiest way to do that would be to contour each side of the split separately and place them together using a technique like what I showed above.
Does that make sense?
Couldn't you just use two axes to do this?
You're right Sean. I was making it too complicated, wasn't I?
Here's a simple implementation of Sean's idea:
margin = .075;
ratio = 3;
h1 = (1-3*margin) / (ratio+1);
h2 = h1*ratio;
ax1 = axes('Position',[.13 margin .775 h1]);
ax2 = axes('Position',[.13, 2*margin+h1, .775, h2]);
[x,y,z] = peaks;
contourf(ax1,x,y,z);
contourf(ax2,x,y,z);
cutoff = 0;
set(ax1,'YLim',[-inf cutoff]);
set(ax2,'YLim',[cutoff inf],'XAxisLocation','top');
Thank you so much, Mike and Sean!
This is very helpful.

Sign in to comment.

More Answers (0)

Categories

Tags

Asked:

on 4 May 2015

Commented:

on 4 May 2015

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!