X-Axis Boxplot Shift
22 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Austin Bollinger
le 10 Juin 2024
Modifié(e) : Adam Danz
le 10 Juin 2024
Is there a way in matlab to use boxplot or boxchart to shift the boxplot to the side of additional data lines such as a scatter or line plot? I am looking to put my scatter point on x-axis 1 and 2 with the boxplot to the side at x-axis 0.5 and 2.5. Image attached of my data and then of an image I found of someone doing this in R.
0 commentaires
Réponse acceptée
Voss
le 10 Juin 2024
% random data
N = 100;
x = randn(N,1);
cats = categorical(randi(2,N,1),[1 2],{'None','LF'});
% create the box plot
figure
h = boxplot(x,cats);
% shift box plots to the left by 0.3
set(h,{'XData'},cellfun(@(x)x-0.3,get(h,'XData'),'UniformOutput',false))
% create the scatter plots
hold on
scatter(1,x(cats == 'None'))
scatter(2,x(cats == 'LF'))
% adjust the xlimits
xlim([0 3])
0 commentaires
Plus de réponses (1)
Adam Danz
le 10 Juin 2024
Modifié(e) : Adam Danz
le 10 Juin 2024
This demo plots the boxchart first and then plots the jittered scatter next to the boxes. This differs from the original request to plot the scatter first and offset the box charts.
rng default
% Prep data
load patients
Gender = categorical(Gender);
Smoker = categorical(Smoker,logical([1 0]),{'Smoker','Nonsmoker'});
groupdata = Gender.*Smoker;
% Create boxchart
fig = figure();
b = boxchart(Diastolic,'GroupByColor',groupdata);
legend('Location','southoutside','orientation','horizontal','NumColumns',4)
ax = ancestor(b(1),'axes');
ax.XTick = [];
ylabel('Diastolic pressure (mmHg)')
set(b, 'MarkerStyle','none')
% Compute x-edges of each box
% Centeres will be computed by averaging x-vertex data of boxes
% BoxWidth is not useful with cat axes so edges must be computed
boxchartparts = vertcat(b.NodeChildren);
isBoxFace = strcmpi(get(vertcat(b.NodeChildren),'Description'), 'Box Face');
boxFaces = boxchartparts(isBoxFace);
drawnow()
[boxLeftEdge, boxRightEdge] = arrayfun(@(h)bounds(h.VertexData(1,:)),boxFaces); % in order of b handles
interBoxInterval = min(boxLeftEdge(2:end) - boxRightEdge(1:end-1)); % assumes >1 box
% For each box, add underlying data via scatter with jittered x values
% Jitter width defined by width between boxes
gap = 0.25*interBoxInterval;
scatWidth = interBoxInterval - 2*gap;
hold on
groupcats = categories(groupdata); % in order of b handles
for i = 1:numel(b)
idx = groupdata == groupcats(i);
yvals = Diastolic(idx);
scatBounds = boxRightEdge(i) + [gap, gap+scatWidth];
xvals = rescale(rand(size(yvals)),scatBounds(1),scatBounds(2));
scatter(xvals,yvals, 70, b(i).BoxEdgeColor, ...
LineWidth = b(i).LineWidth, ...
MarkerFaceColor = b(i).BoxFaceColor, ...
MarkerFaceAlpha = b(i).BoxFaceAlpha);
end
Solution 2: add more categories to the x axis
This demo plots grouped scatter objects on a categorical x axes using categories 1 to n (n=2). It then adds addtional categories to make room for the box charts. Set the interval variable to conrol spacing between boxes and scatter.
% Create data
rng default
data = rand(20,2).*[1.1,.9]+[.2 -.2];
group = [1,2].*ones(height(data),1); % categories are 1:n for n boxes.
% Plot scatter using categorical x values
cats = categorical(group);
s = scatter(cats,data);
% Store original x tick values
ax = ancestor(s(1),'axes');
origTicks = ax.XAxis.TickValues;
% Add more categories to the axes
% This assumes double(categorical(ax.XAxis.Categories))==1:n
ncats = numel(ax.XAxis.Categories);
interval = 1/4; % Space between scatter and boxes.
ax.XAxis.Categories = string(1-interval:interval:ncats+interval);
ax.XAxis.TickValues = origTicks;
% Plot the boxchart at an offset to the scatter
hold on
boxcats = categorical(group - interval);
boxchart(boxcats(:),data(:))
0 commentaires
Voir également
Catégories
En savoir plus sur Data Distribution Plots dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!