Using boxchart, how can I get the boxes to align with my labels?
조회 수: 35 (최근 30일)
이전 댓글 표시
I am using boxchart to plot 8 datasets on the same plot. I'd like them to alternate in color and specify the x-axis labels. I managed to acheive this using a table, but now when I plot the data, the boxes are getting grouped in pairs and the x-axis labels are not aligned properly.
Here is my current output (code below):
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1443772/image.png)
Everything looks good except the labels don't align with the boxes, which are getting grouped in pairs. Does anyone have any ideas on how I can make these labels alignt with the boxes?
roiindx = [1 4 7 8 10]; % pulling specific items from a larger dataset
i=1; % ultimately, this will be in a loop, but I am trying to keep it simple for now
% this is the data, I am pulling 8 ROIs from this data each 5x5pixels
load('extractedROIdata2023.mat')
% simple script to create cell arrays with label data. size = (200x1)
% cats are the 8 different categories
% corrected is really just a logical containing "corrected" & "uncorrected"
[cats, corrected] = generateCategoricalforBoxcharts();
sz = size(right_hduncroi{roiindx(i)});% (5x5 before reshaping)
% reshape selected ROI to be 25x1 before concatenating all into a single
% table which is same size as the cats and corrected label data (200x1)
% right side
rhdunc = double(reshape(right_hduncroi{roiindx(i)},1,sz(1)*sz(2))');
rhdc = double(reshape(right_hdcroi{roiindx(i)},1,sz(1)*sz(2))');
rldunc = double(reshape(right_lduncroi{roiindx(i)},1,sz(1)*sz(2))');
rldc = double(reshape(right_ldcroi{roiindx(i)},1,sz(1)*sz(2))');
% left side
lhdunc = double(reshape(left_hduncroi{roiindx(i)},1,sz(1)*sz(2))');
lhdc = double(reshape(left_hdcroi{roiindx(i)},1,sz(1)*sz(2))');
lldunc = double(reshape(left_lduncroi{roiindx(i)},1,sz(1)*sz(2))');
lldc = double(reshape(left_ldcroi{roiindx(i)},1,sz(1)*sz(2))');
data = [lhdunc; lhdc; lldunc; lldc; rhdunc; rhdc; rldunc; rldc]; % 200x1 double
T = table(cats,data,corrected); % create table with data and labels
dataorder = {'Left HD','Left HD''','Left LD','Left LD''','Right HD','Right HD''','Right LD','Right LD'''};
T.cats = categorical(T.cats,dataorder);
T.corrected = categorical(T.corrected);
boxchart(T.cats,T.data,'GroupByColor',T.corrected)
댓글 수: 2
the cyclist
2023년 7월 27일
이동: Voss
2023년 7월 27일
Can you upload the data file? You can use the paper clip icon in the INSERT section of the toolbar.
채택된 답변
Voss
2023년 7월 27일
편집: Voss
2023년 7월 27일
All this is the same as what you already have:
roiindx = [1 4 7 8 10]; % pulling specific items from a larger dataset
i=1; % ultimately, this will be in a loop, but I am trying to keep it simple for now
% this is the data, I am pulling 8 ROIs from this data each 5x5pixels
load('extractedROIdata2023.mat')
% simple script to create cell arrays with label data. size = (200x1)
% cats are the 8 different categories
% corrected is really just a logical containing "corrected" & "uncorrected"
[cats, corrected] = generateCategoricalforBoxcharts();
sz = size(right_hduncroi{roiindx(i)});% (5x5 before reshaping)
% reshape selected ROI to be 25x1 before concatenating all into a single
% table which is same size as the cats and corrected label data (200x1)
% right side
rhdunc = double(reshape(right_hduncroi{roiindx(i)},1,sz(1)*sz(2))');
rhdc = double(reshape(right_hdcroi{roiindx(i)},1,sz(1)*sz(2))');
rldunc = double(reshape(right_lduncroi{roiindx(i)},1,sz(1)*sz(2))');
rldc = double(reshape(right_ldcroi{roiindx(i)},1,sz(1)*sz(2))');
% left side
lhdunc = double(reshape(left_hduncroi{roiindx(i)},1,sz(1)*sz(2))');
lhdc = double(reshape(left_hdcroi{roiindx(i)},1,sz(1)*sz(2))');
lldunc = double(reshape(left_lduncroi{roiindx(i)},1,sz(1)*sz(2))');
lldc = double(reshape(left_ldcroi{roiindx(i)},1,sz(1)*sz(2))');
data = [lhdunc; lhdc; lldunc; lldc; rhdunc; rhdc; rldunc; rldc]; % 200x1 double
T = table(cats,data,corrected); % create table with data and labels
dataorder = {'Left HD','Left HD''','Left LD','Left LD''','Right HD','Right HD''','Right LD','Right LD'''};
T.cats = categorical(T.cats,dataorder);
Then, instead of grouping, you can create two separate boxcharts, one for 'corrected' and one not.
idx = strcmp(T.corrected,'corrected');
boxchart(T.cats(idx),T.data(idx));
hold on
boxchart(T.cats(~idx),T.data(~idx));
추가 답변 (1개)
Cris LaPierre
2023년 7월 27일
편집: Cris LaPierre
2023년 7월 27일
This is a result of your data. You are missing data for some of your categories. If you had data in each category, your boxchart should have a blue and orange box centered on each tick. Your figure starts with orange, which means you have no data for T.cats="Left HD" and T.corrected="false".
Here's how the data should look if you have data for each categorical
cats = ["Left HD";"Left HD'";"Left LD";"Left LD'";"Right HD";"Right HD'";"Right LD";"Right LD'"];
cats = repmat(cats,10,1);
data = rand(length(cats),1);
corrected = rand(length(cats),1)>0.5;
dataorder = {'Left HD','Left HD''','Left LD','Left LD''','Right HD','Right HD''','Right LD','Right LD'''};
T = table(cats,data,corrected);
T.cats = categorical(T.cats,dataorder);
T.corrected = categorical(T.corrected);
boxchart(T.cats,T.data,'GroupByColor',T.corrected)
legend
Here's what it looks like if you are missing data in some categories.
T(T.cats=="Left HD" & T.corrected=="false",:)=[];
T(T.cats=="Left HD'" & T.corrected=="true",:)=[];
T(T.cats=="Left LD" & T.corrected=="false",:)=[];
T(T.cats=="Left LD'" & T.corrected=="true",:)=[];
T(T.cats=="Right HD" & T.corrected=="false",:)=[];
T(T.cats=="Right HD'" & T.corrected=="true",:)=[];
T(T.cats=="Right LD" & T.corrected=="false",:)=[];
T(T.cats=="Right LD'" & T.corrected=="true",:)=[];
figure
boxchart(T.cats,T.data,'GroupByColor',T.corrected)
legend
댓글 수: 2
Cris LaPierre
2023년 7월 28일
편집: Cris LaPierre
2023년 7월 28일
In a grouped boxchart, grouped boxes share a tick. So if you have 8 ticks and 2 groups, there should be 16 boxes. If you wanted to use the grouped option here, you would have 4 ticks and 2 groups, with the legend indicating the category.
roiindx = [1 4 7 8 10]; % pulling specific items from a larger dataset
i=1; % ultimately, this will be in a loop, but I am trying to keep it simple for now
% this is the data, I am pulling 8 ROIs from this data each 5x5pixels
load("extractedROIdata2023.mat")
sz = numel(right_hduncroi{roiindx(i)});
grpnames = categorical(["Left HD","Left HD'","Left LD","Left LD'","Right HD","Right HD'","Right LD","Right LD'"]);
catnames = categorical(["Left HD","Left LD","Right HD","Right LD"]);
c = repelem("corrected",sz,1);
unc = repelem("uncorrected",sz,1);
% reshape selected ROI to be 25x1 before concatenating all into a single
% table which is same size as the cats and corrected label data (200x1)
% right side
rhdunc = right_hduncroi{roiindx(i)}(:);
rhdc = right_hdcroi{roiindx(i)}(:);
rldunc = right_lduncroi{roiindx(i)}(:);
rldc = right_ldcroi{roiindx(i)}(:);
% left side
lhdunc = left_hduncroi{roiindx(i)}(:);
lhdc = left_hdcroi{roiindx(i)}(:);
lldunc = left_lduncroi{roiindx(i)}(:);
lldc = left_ldcroi{roiindx(i)}(:);
data = [lhdunc; lhdc; lldunc; lldc; rhdunc; rhdc; rldunc; rldc]; % 200x1 double
corrected = [unc;c;unc;c;unc;c;unc;c];
cats = repelem(catnames([1 1 2 2 3 3 4 4]),sz,1);
cats = cats(:);
grp = repelem(grpnames([1 2 3 4 5 6 7 8]),sz,1);
grp = grp(:);
T = table(cats,grp,data,corrected); % create table with data and labels
T.corrected = categorical(T.corrected)
boxchart(T.cats,T.data,'GroupByColor',T.corrected)
legend('Location','best')
If you want each box to have its own tick and be a different color, the simplest approach is the one Voss shared.
참고 항목
카테고리
Help Center 및 File Exchange에서 Annotations에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!