Issue in using splitapply to plot data

Hi,
I have an array with 14 columns. Column 3 contains groups of numbers. I would like to plot column 1 vs. column 4 for each group of column 3. I have written the following code,
G = findgroups(val(:, 3));
splitapply(@plot, val(:, 1), val(:, 4), G);
From my data, I should be getting 6 plots within the figure. But I am getting only a single plot. So what is the issue in my code?
Also how to write legend using splitapply?
Thanks.

 Respuesta aceptada

Star Strider
Star Strider el 23 de Mzo. de 2020
One approach:
D = load('val.mat');
val = D.val;
G = findgroups(val(:, 3));
figure
hold on
Y = splitapply(@(x){plot(x(:,[1 4]))}, val, G);
hold off
Another approach:
D = load('val.mat');
val = D.val;
G = findgroups(val(:, 3));
Y = splitapply(@(x){x(:,[1 4])}, val, G);
figure
hold on
for k = 1:numel(Y)
plot(Y{k})
end
hold off
grid
legend(compose('Group %d', 1:6), 'Location','eastoutside')
I prefer the second approach, however it is possible to use plot with splitapply, as the first approach demonstrates.

8 comentarios

vanrapa
vanrapa el 23 de Mzo. de 2020
2nd approach is better to include loop variables in legend
Star Strider
Star Strider el 23 de Mzo. de 2020
You can probably include the legend in the first approach as well. I only included them in the second because I thought of it only then.
vanrapa
vanrapa el 24 de Mzo. de 2020
Editada: vanrapa el 24 de Mzo. de 2020
for k = 1:numel(Y)
plot(Y{k})
legendLabel{k}= ['Channel' num2str(k)]
end
legend(legendLabel)
I used the above code for legend. But even then, here, since my column 3 data contains values between 1 to 6, this code is fine. But if instead of 1 to 6, if I contain values of 1 to 5 and 8, even then the legend will show only Channel 6 because the code uses 'numel'. So I don't know how to extract the value using which the data is split into 6 groups using splitapply. I want to include that value in legend. Using 'unique(G)' doesnt seem to help.
I dont seem to know how to do that using 1st or 2nd method.
If the group numbers are 1:5 and 8, then the code changes to:
GN = [1:5 8];
legend(sprintfc('Channel %d',GN))
You can avoid the loop by using the undocumented sprintfc function. Everyone has it.
The full code then becomes:
G = findgroups(val(:, 3));
figure
hold on
Y = splitapply(@(x){plot(x(:,[1 4]))}, val, G);
hold off
grid
GN = [1:5 8];
legend(sprintfc('Channel %d',GN))
vanrapa
vanrapa el 24 de Mzo. de 2020
Thanks. Didn't know about the sprintfc before. But [1:5 8] or [1:6] is not fixed. The number of channels and the numbers of the channel will vary in each file. So I have to write code for a generic legend. So how to do that?
I have no information with respect to how the channels are designated in the file. If they are in ‘val(:,3)’, this could work:
GN = unique(val(:,3),'stable');
legend(sprintfc('Channel %d',GN))
If they are not defined in the file, then it would be necessary to hard-code them individually for each file, or provide some sort of pre-defined hard-coded look-up table to define them.
vanrapa
vanrapa el 24 de Mzo. de 2020
Channels will be in val(;,3) and it is working. Thanks
Star Strider
Star Strider el 24 de Mzo. de 2020
As always, my pleasure!

Iniciar sesión para comentar.

Más respuestas (0)

Productos

Versión

R2017a

Preguntada:

el 23 de Mzo. de 2020

Comentada:

el 24 de Mzo. de 2020

Community Treasure Hunt

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

Start Hunting!

Translated by