-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmaineffects.m
More file actions
196 lines (148 loc) · 5.26 KB
/
maineffects.m
File metadata and controls
196 lines (148 loc) · 5.26 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
%% Main Effects Plot
%GNU General Public License v3.0
%By Stefan Thanheiser: https://orcid.org/0000-0003-2765-1156
%
%Part of the paper:
%
%Thanheiser, S.; Haider, M.
%Dispersion Model for Level Control of Bubbling Fluidized Beds with
%Particle Cross-Flow
%Chemical Engineering Research and Design 2025
%
%All data, along with methodology reports and supplementary documentation,
%is published in the data repository:
%https://doi.org/10.5281/zenodo.7924693
%
%All required files for this function can be found in the software
%repository:
%https://doi.org/10.5281/zenodo.7948224
%
%
%
%This function creates a main effects plot based on multiple independent
%variables (X) grouped into groups of roughly equal values. The secondary
%groups secgrps can be used to illustrate the effect of a dependent
%variable within the effects-plot of another dependent variable. Y is the
%response variable.
%
%
%Required products, version 24.1:
% - MATLAB
%Necessary files, classes, functions, and scripts:
% - None
%%
function [fig,tiles,ax]=maineffects(Y,X,grps,secgrps,figidx,xnames,yname)
n=length(Y);
grpsRange=grps;
%Center parameters around grouping values, readjust groups
ngrps=length(grps);
Xcentered=NaN(size(X));
for i=1:ngrps
[Xcentered(:,i),grps{i}]=center(X(:,i),grps{i});
end
%Get combinations of parameters
combs=table2array(combinations(grps{:}));
ncombs=size(combs,1);
%Assign each observation to a set of parameters
combbox=permute(combs,[3,2,1]);
combbox=repmat(combbox,n,1,1);
Xbox=repmat(Xcentered,1,1,ncombs);
%assig(i,j)==true --> observation i was recorded at parameter set j
assig=squeeze(all(Xbox==combbox,2));
clear('combbox','Xbox');
%Sort observations and calculate mean of each parameter combination
nobs=arrayfun(@(x) nnz(assig(:,x)),1:ncombs);
Ysorted=NaN(ncombs,max(nobs));
for i=1:ncombs
idx=find(assig(:,i));
Ysorted(i,1:length(idx))=Y(idx);
end
Ysorted=mean(Ysorted,2,'omitnan');
% %Throw warning when some of the parameter combinations are missing
% if any(isnan(Ysorted))
% getstr=@(x) strjoin(compose('%s=%f',string(xnames)',combs(x,:)'),', ');
% str=arrayfun(getstr,find(isnan(Ysorted)),'UniformOutput',false);
% warning(['The following parameter sets are missing:\n%s\n',...
% 'This will likely lead to misleading results'],strjoin(str,'\n'));
% end
%Set up figure
fig=figure(figidx);
clf(fig);
colors=gca().ColorOrder;
ax=cell(1,ngrps);
%Create tiles
tiles=tiledlayout(fig,'horizontal','TileSpacing','compact');
for i=1:ngrps
ax{i}=nexttile;
hold(ax{i},'on');
if ~isnan(secgrps(i))
s=secgrps(i);
n=length(grps{s});
legItems=cell(n,1);
for j=1:n
%Plot mean of secondary group
idxcell=arrayfun(@(prim) combs(:,i)==prim & combs(:,s)==grps{s}(j),grps{i},'UniformOutput',false);
y=cellfun(@(x) mean(Ysorted(x),'omitnan'),idxcell);
plot(ax{i},grps{i},y,'Color',colors(j,:));
%Overlay actual values
idx=any([idxcell{:}],2);
idx=any(assig(:,idx),2);
scatter(ax{i},X(idx,i),Y(idx),20,colors(j,:));
%Create legend item (dummy plot)
legItems{j}=plot(ax{i},NaN,NaN,'Color',colors(j,:),'Marker','o','MarkerSize',sqrt(20));
end
legItems=[legItems{:}];
else
%Scatter all values when there is no secondary group
scatter(ax{i},X(:,i),Y,20,'k');
end
%Plot total mean
y=arrayfun(@(x) mean(Ysorted(combs(:,i)==x),'omitnan'),grps{i});
plot(ax{i},grps{i},y,'-.k');
%Set legend
if ~isnan(secgrps(i))
name=strsplit(xnames{s},' ');
if length(name)>1
unit=string(extractBetween(name{2},'(',')'));
if strcmp(unit,"-")
unit=string();
end
else
unit=string();
end
legLabels=compose('%s=%.1f %s',repmat(string(name{1}),n,1),grps{s}',repmat(unit,n,1));
legend(ax{i},legItems,legLabels,'Location','northoutside');
end
hold(ax{i},'off');
%Set x label
xlabel(ax{i},xnames{i});
%Set x limit
xlimit=[ax{i}.XLim;min(grpsRange{i}),max(grpsRange{i})];
ax{i}.XLim=boundary(xlimit);
end
%Configure axes
ax=[ax{:}];
if length(ax)>1
%Set common y limits
ylimits=boundary(cell2mat(get(ax,'YLim')));
set(ax,'YLim',ylimits);
%Remove y tick labels except in first plot
set(ax(2:end),'YTickLabelMode','manual');
set(ax(2:end),'YTickLabel',[]);
end
%Set y axis label
ylabel(ax(1),yname);
end
function [x,meancenters]=center(x,approx)
cats=interp1(approx,approx,x,'nearest','extrap');
meancenters=arrayfun(@(y) mean(x(cats==y)),approx);
meancenters(isnan(meancenters))=[];
if length(meancenters)>1
x=interp1(meancenters,meancenters,x,'nearest','extrap');
else
x=repmat(meancenters,size(x));
end
end
function x=boundary(x)
x=[min(x(:,1)),max(x(:,2))];
end