-
Notifications
You must be signed in to change notification settings - Fork 6
/
sanePColor.m
159 lines (147 loc) · 5.03 KB
/
sanePColor.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
function p = sanePColor(varargin)
%SANEPCOLOR simple wrapper for pcolor
%
% Unlike the built-in pcolor command, this function does not "cut off" the
% last row and column of the input matrix. In this way, sanePColor is
% intended to be as easy to use as imagesc, but allows the user to specify
% the x and y coordinates of each cell if desired. This function is also
% useful as an alternative means of generating images to print to PDF that
% are compatible with OS X's "Preview" PDF viewer (imagesc images appear
% "blurred" when printing to a PDF as a vector graphic and viewed using
% Preview).
%
% NOTE: The imagesc function assumes that each entry in a matrix gets the
% corresponding coordinate in 2-d space. For example, entry (2,3) in the
% matrix is assigned to the coordinate with x = 3, y = 2 when using
% imagesc. The pcolor function assumes that entries correspond to *edges*.
% So entry (2,3) in a matrix corresponds to the value between 2 and 3
% (along the x-axis) and between 1 and 2 (along the y-axis). This is why
% one row and one column are cut off when using pcolor. sanePColor
% behaves like imagesc (i.e. does not cut off data), but uses the "edge
% assignment" data representation required by pcolor. sanePColor uses
% linear or logarithmic interpolation to infer the edges automatically.
%
% Usage: p = sanePColor([x,y],z,[logx],[logy]);
%
%INPUTS:
%
% x: an array of sorted x values. can also specify a min and max x value.
% these values correspond to columns of z. [IF THIS ARGUMENT IS USED,
% MUST ALSO SPECIFY Y VALUES.]
%
% y: an array of sorted y values. can also specify a min and max y value.
% these values correspond to rows of z. [IF THIS ARGUMENT IS USED,
% MUST ALSO SPECIFY X VALUES.]
%
% z: a 2d matrix of values. this matrix determines the color at each
% point.
%
% logx: if this optional argument is set to true, the x-axis will plotted
% in log scale (similar to semilogx).
%
% logy: if this optional argument is set to true, the y-axis will plotted
% in log scale (similar to semilogy).
%
%OUTPUTS:
%
% p: a handle to the resulting pcolor image.
%
% EXAMPLE:
%
% m = membrane;
% p = sanePColor(m);
%
% SEE ALSO: PCOLOR, IMAGE, IMAGESC, SEMILOGX, SEMILOGY, LOGLOG, PADARRAY
%
% AUTHOR: JEREMY R. MANNING
% CONTACT: [email protected]
%CHANGELOG
%3-16-10 JRM Wrote it.
%3-12-12 JRM Support a more diverse range of input configurations.
%9-21-12 JRM Use linear and logistic interpolation to estimate data
% coordinates more accurately.
%10-6-16 JRM Support non-linear and non-log axes (Credit: Benjamin
% Strom suggestion via Mathworks FileExchange)
%parse arguments
if length(varargin) == 1 %just z
z = varargin{1};
x = 1:size(z,2);
y = 1:size(z,1);
[logx,logy] = deal(false);
elseif (length(varargin) >= 4) %x, y, z, logx, and possibly logy
x = varargin{1};
y = varargin{2};
z = varargin{3};
logx = varargin{4};
if length(varargin) >= 5, logy = varargin{5}; else logy = false; end
elseif length(varargin) == 2 %z and logx
z = varargin{1};
logx = varargin{2};
assert(islogical(logx),'logx must be a logical');
if logx
x = logspace(log10(1),log10(size(z,2)),size(z,2));
else
x = 1:size(z,2);
end
logy = false;
y = 1:size(z,1);
else %length(varargin) == 3
if isempty(varargin)
fprintf('\nUsage: p = sanePColor([x,y],z,[logx],[logy]);\n');
fprintf('Type ''help %s'' for more info.\n\n',mfilename);
p = [];
return;
end
%posibility 1: x, y, z
if length(varargin{1}) > 1 && length(varargin{2}) > 1
x = varargin{1};
y = varargin{2};
z = varargin{3};
[logx,logy] = deal(false);
%posibility 2: z, logx, and logy
else
z = varargin{1};
logx = varargin{2};
assert(islogical(logx),'logx must be a logical');
if logx
x = logspace(log10(1),log10(size(z,2)),size(z,2));
else
x = 1:size(z,2);
end
logy = varargin{3};
assert(islogical(logy),'logy must be a logical');
if logy
y = logspace(log10(1),log10(size(z,1)),size(z,1));
else
y = 1:size(z,1);
end
end
end
assert(length(x) == size(z,2),'length(x) must equal size(z,2)');
assert(length(y) == size(z,1),'length(y) must equal size(z,1)');
assert(islogical(logx),'logx must be a logical');
assert(islogical(logy),'logy must be a logical');
z = padarray(z,[1 1],'replicate','post');
if logx
newx = logexpand(x);
else
newx = linexpand(x);
end
if logy
newy = logexpand(y);
else
newy = linexpand(y);
end
p = pcolor(double(real(newx)), double(real(newy)), double(real(z)));
shading flat;
function[ey] = linexpand(y)
%Credit: Benjamin Strom
ey = [y, 0];
ey(end) = 2*ey(end-1) - ey(end-2);
ey = ey - (ey(end-1) - ey(end-2))/2;
function[ex] = logexpand(x)
ex = exp(linexpand(log(x)));
function[x] = prune(x,n)
d = diff(x);
[~,ord] = sort(d);
x(ord(1:n)) = [];