X-Axis Boxplot Shift
조회 수: 16 (최근 30일)
이전 댓글 표시
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. ![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1712776/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1712776/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1712781/image.png)
댓글 수: 0
채택된 답변
Voss
2024년 6월 10일
% 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
추가 답변 (1개)
Adam Danz
2024년 6월 10일
편집: Adam Danz
2024년 6월 10일
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
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1712836/image.png)
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(:))
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1712841/image.png)
댓글 수: 0
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!