-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmT_plotDencities.m
More file actions
282 lines (233 loc) · 9.94 KB
/
mT_plotDencities.m
File metadata and controls
282 lines (233 loc) · 9.94 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
function figHandle = mT_plotDencities(DSet, XVars, Rows, Series, ...
PlotStyle, ptpntNum, varargin)
% Produces subplots of histograms
% INPUT
% XVars [num x-variables] long struct array with fields...
% ProduceVar Function handle. Function accepts 'DSet.P(i).Data' (see
% standard data strcuture information in README).
% Function produces [num trials] long vector of values of this
% variable.
% NumBins Number of histogram bins to use
% FindIncludedTrials
% (optional)
% Function handle. Function accepts 'DSet.P(i).Data' and
% produces a [num trials] long logical of trials to include
% when evaluating this x-variable. Note that trials are only
% included if they meet all inclusion criteria, see 'Series'.
%
% Rows [num subplot rows] long struct array with fields...
% FindIncludedTrials
% Function handle. Function accepts 'DSet.P(i).Data' and
% produces a [num trials] long logical of trials to include
% when evaluating the histograms in this subplot row.
% Note that trials are only
% included if they meet all inclusion criteria, see 'Series'.
%
% Series [num series] long struct array. Each series will be plotted in
% every subplot. Contains fields...
% FindIncludedTrials
% Function handle. Function accepts 'DSet.P(i).Data' and
% produces a [num trials] long logical of trials to include
% when evaluating this series. Note that trials are only
% included if they meet all inclusion criteria.
%
% PlotStyle struct array with fields...
% General
% Which defaults to use, 'computer' or 'paper'
% Scale
% Scales such that the physical area under the probability distributions (which is
% the same for all series and scales) is bigger or smaller. 5 is a
% sensible first value.
% Annotate
% Xaxis [num x-variables] struct array with fields...
% Title optional
% Ticks optional
% TickLabels optional
% InvisibleTickLablels optional. Vector which gives indecies of
% TickLabels. For the labels and ticks corresponding to these indicies,
% ticks will be shown at these locations, no labels.
% Rows [num subplot rows] long struct array with fields...
% Title optional
% Data [num series] long strcut array with fields...
% Name Name of the series (for legend, optional)
% Colour optional
% LineStyle optional string. Options are the standard MATLAB options
% ('-', '--', ':', '-.')
% ptpntNum Which participant to plot for?
% varargin Figure handle for the figure to plot onto. If the old figure
% has the same subplot structure, then all the data in the old
% subplots will be retianed.
% HISTORY
% Reviewed 2020
if ~isempty(varargin)
figHandle = varargin{1};
hold on
else
figHandle = figure;
end
if ~isfield(PlotStyle, 'General') || strcmp(PlotStyle.General, 'computer')
plotLineWidth = 4;
axisLineWidth = 4;
refLineWidth = 2;
fontSize = 30;
tickDirection = 'out';
elseif strcmp(PlotStyle.General, 'paper')
plotLineWidth = 1.5;
axisLineWidth = 1;
refLineWidth = 0.5;
fontSize = 10;
tickDirection = 'out';
end
% Matlab uses a particualar numbering system for subplots. Find an array
% that converts from matrix index to matlab subplot number.
subplotWidth = length(XVars);
subplotHeight = length(Rows);
subplotIdx = NaN(subplotWidth, subplotHeight);
subplotIdx(:) = 1 : length(subplotIdx(:));
subplotIdx = subplotIdx';
%% Make the plots
for iPltRow = 1 : subplotHeight
for iPltCol = 1 : subplotWidth
% Do the plotting itself
if (subplotHeight == 1) && (subplotWidth == 1)
subplotObj = gca;
hold on
else
subplotObj = subplot(subplotHeight, subplotWidth, ...
subplotIdx(iPltRow, iPltCol));
hold on
end
% Loop through all the series to be plotted
for iSeries = 1 : length(Series)
% What colour should we plot in?
if isfield(PlotStyle.Data, 'Colour') ...
&& ~isempty(PlotStyle.Data(iSeries).Colour)
plottingColour = PlotStyle.Data(iSeries).Colour;
% Otherwise use default colours
else
plottingColour = mT_pickColour(iSeries);
% Store for legend
PlotStyle.Data(iSeries).Colour = plottingColour;
end
% Plotting time!
relData = XVars(iPltCol).ProduceVar(DSet.P(ptpntNum).Data);
incTrials = findIncludedTrials(DSet, ptpntNum, ...
XVars, iPltCol, Rows, iPltRow, Series, iSeries);
[histVals, edges] = histcounts(relData(incTrials), ...
XVars(iPltCol).NumBins, ...
'Normalization', 'pdf');
centres = edges(1:end-1) + (0.5*diff(edges));
% Have we requested a specific line style?
if isfield(PlotStyle, 'Data') ...
&& isfield(PlotStyle.Data(iSeries), 'LineStyle') ...
&& ~isempty(PlotStyle.Data(iSeries).LineStyle)
lineStyle = PlotStyle.Data(iSeries).LineStyle;
else
lineStyle = '-';
PlotStyle.Data(iSeries).LineStyle = '-';
end
plot(centres, histVals, ...
'Color', plottingColour, ...
'LineWidth', plotLineWidth, ...
'LineStyle', lineStyle);
end
if isfield(PlotStyle, 'Xaxis') ...
&& isfield(PlotStyle.Xaxis(iPltCol), 'Ticks')
xlim(PlotStyle.Xaxis(iPltCol).Ticks([1, end]))
xticks(PlotStyle.Xaxis(iPltCol).Ticks)
end
if isfield(PlotStyle, 'Xaxis') ...
&& isfield(PlotStyle.Xaxis(iPltCol), 'TickLabels')
xticklabels(PlotStyle.Xaxis(iPltCol).TickLabels)
end
if isfield(PlotStyle, 'Xaxis') ...
&& isfield(PlotStyle.Xaxis(iPltCol), 'InvisibleTickLablels')
if ~isfield(PlotStyle.Xaxis(iPltCol), 'Ticks')
error(['Must specify ticks if want to specify invisible ', ...
'ticks. Otherwise get nasty effects as invisible ticks ', ...
'functionality works by changing and *freezing* tick ', ...
'labels.'])
end
ax = gca;
labels = string(ax.XTickLabel);
labels(PlotStyle.Xaxis(iPltCol).InvisibleTickLablels) = ' ';
ax.XTickLabel = labels;
end
% Remove y-ticks
set(gca,'ytick',[])
set(gca,'yticklabel',[])
% Set y-limits in a way to ensure constant area accross all plots
xScale = diff(xlim);
yEndPoints = [0, PlotStyle.Scale]/xScale;
ylim(yEndPoints)
% Titles
if isfield(PlotStyle, 'Xaxis') ...
&& isfield(PlotStyle.Xaxis(iPltCol), 'Title')
xLabel = PlotStyle.Xaxis(iPltCol).Title;
else
xLabel = [];
end
if isfield(PlotStyle, 'Rows') ...
&& isfield(PlotStyle.Rows(iPltRow), 'Title')
yLabel = PlotStyle.Rows(iPltRow).Title;
else
yLabel = [];
end
if iPltCol == 1; ylabel(yLabel, 'FontSize',fontSize); end
if iPltRow == subplotHeight; xlabel(xLabel, 'FontSize',fontSize); end
% Other properties
subplotObj.LineWidth = axisLineWidth;
subplotObj.FontSize = fontSize;
set(gca, 'TickDir', tickDirection);
% Add annotations
if isfield(PlotStyle, 'Annotate')
labelText = ['{\bf ' PlotStyle.Annotate(iPltRow, iPltCol).Text ' }'];
plotLable = text(-0.08,1.04, ...
labelText, ...
'Units', 'Normalized', 'VerticalAlignment', 'Bottom');
plotLable.FontSize = fontSize;
end
end
end
%% Make the legends
% Making the legend is a little complicated in this case. We are going
% to trick MATLAB and draw invisible new lines.
% Set legend
if isfield(PlotStyle, 'Data') && isfield(PlotStyle.Data, 'Name')
if (subplotHeight == 1) && (subplotWidth == 1)
% Do nothing, there is only one plot to pick from
else
subplot(subplotHeight, subplotWidth, ...
subplotIdx(ceil(subplotHeight/2), end));
hold on
end
legendLabels = cell(1, length(PlotStyle.Data));
for iLabel = 1 : length(legendLabels)
legendLabels{iLabel} = PlotStyle.Data(iLabel).Name;
legendLine(iLabel) = ...
errorbar(NaN, NaN, NaN, NaN, ...
'Color', PlotStyle.Data(iLabel).Colour, ...
'LineWidth', plotLineWidth, ...
'LineStyle', PlotStyle.Data(iLabel).LineStyle);
end
legObj = legend(legendLine, legendLabels{:});
legend boxoff
legObj.FontSize = fontSize;
legObj.LineWidth = axisLineWidth;
legObj.ItemTokenSize(1) = 30;
end
end
function includedData = findIncludedTrials(DSet, iPtpnt, XVars, iX, ...
Row, iR, Series, iS)
% Find the trials meeting all inclusion criteria
if isfield(XVars, 'FindIncludedTrials')
includedData ...
= XVars(iX).FindIncludedTrials(DSet.P(iPtpnt).Data) ...
& Row(iR).FindIncludedTrials(DSet.P(iPtpnt).Data) ...
& Series(iS).FindIncludedTrials(DSet.P(iPtpnt).Data);
else
includedData ...
= Row(iR).FindIncludedTrials(DSet.P(iPtpnt).Data) ...
& Series(iS).FindIncludedTrials(DSet.P(iPtpnt).Data);
end
end