Commit 949fe68c authored by Tom's avatar Tom

now a working function

parent 52fe9835
......@@ -2,48 +2,104 @@
% it might be that 'patch' is a much better plotting function to plot the
% densities than 'area'; it seems to handle over-plotting of different
% areas with different zero lines very well. This would avoid the horrible
% gymnastics that the repeated measures lineplot currently has to deal
% gymnastics that the repeated measures raincloudplot currently has to deal
% with.
% This is a work-in-progress example inspired by this post on Matlab
% answers https://uk.mathworks.com/matlabcentral/answers/1387-area-plot-with-gradient
% For that reason the density plots also now have colour gradients which I
% think look rather nice...
zero_line_for_second_plot = 1.1;
%% TO-DO:
% Change YTick and YTicklabel to meaningful things (passed as input argument?)
% Option to rotate plot by 90'
% Patch can create colour gradients using the 'interp' option to
% 'FaceColor'. Allow this?
nbins = 200;
ndatapoints = 80;
% h = toy_example_with_patch(data, colours)
% h is a cell array of the figure parts
function h = toy_example_with_patch(d,cl)
%% check dimensions of data
[nper, nseries] = size(d);
% make sure we have enough colours
assert(all(size(cl) == [nseries 3]), 'number of colors does not match number of plot series');
d = abs(randn(1,ndatapoints).^1.2);
[ks,x] = ksdensity(d,'NumPoints',nbins);
%%
d2 = abs(randn(1,ndatapoints).^0.7);
[ks2,x2] = ksdensity(d2,'NumPoints',nbins);
% TO-DO: These shouldn't be hard-coded, but calculated somehow. How?
% (spacings between rainclouds)
% ALSO NOTE: This way plots the first data in the series on the top
ks_offsets = [2 1 0];
cl = flipud(cbrewer('seq','Purples',nbins));
cl2 = flipud(cbrewer('seq','Greens',nbins));
% Probably okay to hard-code this as it just determines the granularity of
% the density estimate
nbins = 200;
f = ks;
f2 = ks2 + zero_line_for_second_plot;
for i = 1:nper
for j = 1:nseries
% calculate kernel densities
[ks{i,j},x{i,j}] = ksdensity(d{i,j},'NumPoints',nbins);
% TO-DO: Switch here to use alternative methods to estimate density (e.g. RASH)
% calculate patch vertices from kernel density
verts{i,j} = [x{i,j}', ks{i,j}'+ ks_offsets(i); x{i,j}', ones(nbins,1)*ks_offsets(i)];
end
end
% Define the vertices: the points at (x, f(x)) and (x, 0)
N = length(x);
verts = [x(:), f(:); x(:) zeros(nbins,1)];
verts2 = [x2(:), f2(:); x2(:) ones(nbins,1)*zero_line_for_second_plot]; % give it a different zero
% Define the faces to connect each adjacent f(x) and the corresponding points at y = 0.
q = (1:N-1)';
faces = [q, q+1, q+N+1, q+N];
q = (1:nbins-1)';
faces = [q, q+1, q+nbins+1, q+nbins];
figure; hold on
p = patch('Faces', faces, 'Vertices', verts, 'FaceVertexCData', [cl;cl], 'FaceColor', 'interp', 'EdgeColor', 'none', 'FaceAlpha',0.5);
p2 = patch('Faces', faces, 'Vertices', verts2, 'FaceVertexCData', [cl2;cl2], 'FaceColor', 'interp', 'EdgeColor', 'none', 'FaceAlpha',0.5);
%% jitter for the raindrops
% TO-DO: These should probably not be hardcoded either...
jitwidth = 0.15;
jit = jitwidth + rand(1,ndatapoints) * jitwidth;
jit2 = jitwidth + rand(1,ndatapoints) * jitwidth;
sz = 100;
s = scatter(d,-jit,'MarkerFaceColor',cl(15,:),'MarkerEdgeColor','none', 'MarkerFaceAlpha', 0.5, 'SizeData', sz);
s2 = scatter(d2,-jit2+zero_line_for_second_plot,'MarkerFaceColor',cl2(15,:),'MarkerEdgeColor','none', 'MarkerFaceAlpha', 0.5, 'SizeData', sz);
for i = 1:nper
for j = 1:nseries
jit{i,j} = jitwidth + rand(1,length(d{i,j})) * jitwidth;
end
end
%% means
mnz = cellfun(@mean,d);
%% plot
% note - we *could* plot everything here in one big loop, but then
% different figure parts would overlay each other in a silly way.
figure; hold on
% patches
for i = 1:nper
for j = 1:nseries
% plot patches
h.p{i,j} = patch('Faces',faces,'Vertices',verts{i,j},'FaceVertexCData',[cl(j,:)],'FaceColor','flat','EdgeColor', 'none', 'FaceAlpha',0.5);
% scatter rainclouds
h.s{i,j} = scatter(d{i,j},-jit{i,j} + ks_offsets(i),'MarkerFaceColor',cl(j,:),'MarkerEdgeColor','none', 'MarkerFaceAlpha', 0.5, 'SizeData', sz);
end
end
% mean lines
for i = 2:nper % note 2, not 1. We have nper-1 lines because lines connect pairs of points
for j = 1:nseries
line(mnz([i-1 i],j),ks_offsets([i-1 i]),'LineWidth', 4,'Color',cl(j,:));
end
end
% mean dots
for i = 1:nper
for j = 1:nseries
h.m(i,j) = scatter(mnz(i,j),ks_offsets(i),'MarkerFaceColor',cl(j,:),'MarkerEdgeColor',[0 0 0], 'MarkerFaceAlpha', 1, 'SizeData', sz*2, 'LineWidth', 2);
end
end
% keyboard
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment