Boxchartで各Boxの色を変えたい

現在、以下のスクリプトを作成しBoxchartを作成しています。各Boxの色を変えたいのですが(例えば、左から赤・青・緑・紫)、うまくできません。Boxplotではなく、Boxchartでの方法を教えていただきたいです。よろしくお願いいたします。
tbl1 = readtable('File.csv');%フォルダー内から呼び出し(複数のシートに分ける必要)
TimeOrder = {'A','B','C','D'};%横軸を定義
tbl1.Time = categorical(tbl1.Time,TimeOrder);%データを時間ごとで分類
boxchart(tbl1.Time,tbl1.Variable,'GroupByColor',tbl1.Protocol)%BoxChartの作成
b1 = boxchart(tbl1.Time,tbl1.Variable,'GroupByColor',tbl1.Protocol) %BoxChart格納
meanValue1 = groupsummary(tbl1.Varible,tbl1.Time,'mean');
hold on
plot(meanValue1,'-ok')
plot1 = plot(meanValue1,'-ok')
plot1.LineWidth = 1;
hold off
title('%TQ');
b1.BoxFaceColor = '#A2142F'; %ボックス色の変更
b1.MarkerStyle = 'none'; %マーカースタイルの変更
ylim([0 100]) %y軸の範囲を変更
b1 = gca;%フォントサイズの変更
b1.FontSize = 14;
b1.FontName = 'Times New Roman';%フォントタイプの変更
b1.TickDir = 'out'%メモリ線の位置
b1.FontWeight = 'bold';%ボールド体に変更
b1.XTickLabel = [];
yticks(0:20:100);
b1.LineWidth = 1; % 軸の枠線の太さを設定
b1.XRuler.Axle.LineWidth = 1; % x軸のメモリの太さを設定
b1.YRuler.Axle.LineWidth = 1

2 Comments

Kojiro Saito
Kojiro Saito on 28 Jul 2024
再現できるデータがあればコミュニティでも回答しやすくなると思いますが、色データで与えているtbl1.Protocolにはどのようなデータが含まれていますか?
Raki
Raki on 29 Jul 2024
ご質問ありがとうございます。データファイルを添付しておりますので、ご確認いただけますと幸いです。
また、各Boxに個人データをプロットする方法ももしご存じであれば、ご教示いただきたいです。
よろしくお願いいたします。

Sign in to comment.

 Accepted Answer

共有いただいたFile.csvのProtocolはデータがMのみなので、GroupByColorで指定しても1色になってしまいます。
GroupByColortbl1.Timeを指定すればTimeの値で色分けされます。
元のFile.csvではカラム名がVaiableになっていたので、Variableに変更したファイルを添付しています。
colororder関数を使って左から赤、青、緑、紫のHEX値を指定します。
tbl1 = readtable('File.csv');%フォルダー内から呼び出し(複数のシートに分ける必要)
TimeOrder = {'A','B','C','D'};%横軸を定義
tbl1.Time = categorical(tbl1.Time,TimeOrder);%データを時間ごとで分類
b1 = boxchart(tbl1.Time,tbl1.Variable,'GroupByColor',tbl1.Time, 'MarkerStyle', 'none');
colororder(["#A2142F", "#0072BD", "#77AC30", "#7E2F8E"]); % 左から赤・青・緑・紫に変更
ただ、GroupByColorは同じX軸にデータ系列を複数プロットするために使われるため、X軸のA、B、C、Dの上にデータが表示されない問題があります。
boxchartではデータの中身毎に色を変えるのが現状サポートされていないので、複数回boxchartを実行することで色を替えられます。
for n=1:length(TimeOrder)
idx = tbl1.Time == TimeOrder{n};
boxchart(tbl1.Time(idx, :), tbl1.Variable(idx, :));
if n == 1
hold on
elseif n == length(TimeOrder)
hold off
end
end
colororder(["#A2142F", "#0072BD", "#77AC30", "#7E2F8E"]); % 左から赤・青・緑・紫に変更
title('%TQ');
ylim([0 100]) %y軸の範囲を変更
ax = gca;%フォントサイズの変更
ax.FontSize = 14;
ax.FontName = 'Times New Roman';%フォントタイプの変更
ax.FontWeight = 'bold';%ボールド体に変更
yticks(0:20:100);
ax.LineWidth = 1; % 軸の枠線の太さを設定
meanValue1 = groupsummary(tbl1.Variable,tbl1.Time,'mean');
hold on
plot1 = plot(categorical(TimeOrder), meanValue1,'-ok');
plot1.LineWidth = 1;
hold off

6 Comments

Raki
Raki on 29 Jul 2024
ご丁寧にありがとうございます。無事にボックスごとの色分けができそうですm(__)m
加えて、各ボックスに個人データをプロットすることは可能でしょうか?ボックスはそのままで、上に個人プロットを乗せるイメージです。
Participantの値の順番にplotを行うことで個人データの重畳を実現できます。
tbl1 = readtable('https://jp.mathworks.com/matlabcentral/answers/uploaded_files/1742306/File.csv');%フォルダー内から呼び出し(複数のシートに分ける必要)
TimeOrder = {'A','B','C','D'};%横軸を定義
tbl1.Time = categorical(tbl1.Time,TimeOrder);%データを時間ごとで分類
for n=1:length(TimeOrder)
idx = tbl1.Time == TimeOrder{n};
boxchart(tbl1.Time(idx, :), tbl1.Variable(idx, :));
if n == 1
hold on
elseif n == length(TimeOrder)
hold off
end
end
colororder(["#A2142F", "#0072BD", "#77AC30", "#7E2F8E"]); % 左から赤・青・緑・紫に変更
title('%TQ');
ylim([0 100]) %y軸の範囲を変更
ax = gca;%フォントサイズの変更
ax.FontSize = 14;
ax.FontName = 'Times New Roman';%フォントタイプの変更
ax.FontWeight = 'bold';%ボールド体に変更
yticks(0:20:100);
ax.LineWidth = 1; % 軸の枠線の太さを設定
meanValue1 = groupsummary(tbl1.Variable,tbl1.Time,'mean');
hold on
plot1 = plot(categorical(TimeOrder), meanValue1,'-ok');
plot1.LineWidth = 1;
hold off
% 個人のデータのプロット
tbl2 = sortrows(tbl1, "Participant"); % Participantの値でソート
hold on
for n=min(tbl2.Participant):max(tbl2.Participant)
plot(tbl2.Time, tbl2.Variable, '-o', Color="#cccccc")
end
hold off
Raki
Raki on 30 Jul 2024
ご丁寧にありがとうございます。以下のスクリプトで試したところ添付画像のような図を得ることが出来ました。最後に1点、個々人のデータポイントをボックスの上ではなく、真横に示すことはできますでしょうか?中央値や外れ値とも重なってしまうのでもし可能であれば嬉しいです。難しければ、軸の左右にばらばらに示すことはかのうでしょうか(今は直線的に表示されています)。
tbl1 = readtable('File.csv');%フォルダー内から呼び出し(複数のシートに分ける必要)
TimeOrder = {'A','B','C','D'};%横軸を定義
tbl1.Time = categorical(tbl1.Time,TimeOrder);%データを時間ごとで分類
for n=1:length(TimeOrder)
idx = tbl1.Time == TimeOrder{n};
boxchart(tbl1.Time(idx, :), tbl1.Variable(idx, :));
if n == 1
hold on
elseif n == length(TimeOrder)
hold off
end
end
colororder(["#A2142F", "#0072BD", "#77AC30", "#7E2F8E"]); % 左から赤・青・緑・紫に変更
title('%TQ');
ylim([0 100]) %y軸の範囲を変更
ax = gca;%フォントサイズの変更
ax.FontSize = 14;
ax.FontName = 'Times New Roman';%フォントタイプの変更
ax.FontWeight = 'bold';%ボールド体に変更
yticks(0:20:100);
ax.LineWidth = 1; % 軸の枠線の太さを設定
meanValue1 = groupsummary(tbl1.Variable,tbl1.Time,'mean');
% 個人のデータのプロット
tbl2 = sortrows(tbl1, "Participant"); % Participantの値でソート
jitterAmount = 1; % データポイントをずらす量
hold on
for n=min(tbl2.Participant):max(tbl2.Participant)
plot(tbl2.Time, tbl2.Variable, 'diamond', Color="#000000", MarkerSize=5)
end
hold off
hold on
plot1 = plot(categorical(TimeOrder), meanValue1,'ok');
plot1.LineWidth = 1;
plot1.MarkerFaceColor = 'k'; % マーカーの塗りつぶし色
plot1.MarkerEdgeColor = 'k'; % マーカーの縁の色
hold off
Timeの列を一旦カテゴリー配列からfindgroupsで数値に変換して、オフセット (下記では0.3)を付けてプロットしたら実現できます。
hold on
% グループ番号に変換
tempVar = findgroups(tbl2.Time);
for n=min(tbl2.Participant):max(tbl2.Participant)
plot(tempVar+0.3, tbl2.Variable, 'diamond', Color="#000000", MarkerSize=5)
end
hold off
Raki
Raki on 31 Jul 2024
無事作図することが出来ました。本当にありがとうございました。
Kojiro Saito
Kojiro Saito on 31 Jul 2024
@Rakiさん、解決して良かったです。
最後に、回答の採用ボタンを押していただけますでしょうか。

Sign in to comment.

More Answers (0)

Products

Release

R2024a

Asked:

on 26 Jul 2024

Commented:

on 31 Jul 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!