Skip to content

Commit 8845bc9

Browse files
committed
feat: add support for showing multiple lines in a stacked plot
1 parent 957f72a commit 8845bc9

File tree

3 files changed

+97
-4
lines changed

3 files changed

+97
-4
lines changed

src/visualize/+mag/+graphics/+chart/Stackedplot.m

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,25 @@
4242
error("Mismatch in number of colors for number of plots.");
4343
end
4444

45+
% Check if layout already has a stack layout.
46+
existingGraphics = layout.Children;
47+
48+
if isempty(existingGraphics) || ~isequal(existingGraphics(1).Type, "tiledlayout")
49+
stackLayout = tiledlayout(layout, Ny, 1, TileSpacing = "tight", Padding = "tight", Layout = axes.Layout);
50+
else
51+
stackLayout = existingGraphics(1);
52+
end
53+
4554
% Create custom stacked plot.
4655
graph = matlab.graphics.chart.primitive.Line.empty(0, Ny);
47-
stackLayout = tiledlayout(layout, Ny, 1, TileSpacing = "tight", Padding = "tight", Layout = axes.Layout);
4856

4957
for y = 1:Ny
5058

51-
ax = nexttile(stackLayout);
59+
ax = nexttile(stackLayout, y);
60+
61+
hold(ax, "on");
62+
resetAxesHold = onCleanup(@() hold(ax, "off"));
63+
5264
graph(y) = plot(ax, xData, yData(:, y), this.MarkerStyle{:}, this.LineCustomization{:}, Color = this.Colors(y, :));
5365

5466
if this.EventsVisible && ~isempty(data.Properties.Events)

src/visualize/+mag/+graphics/+style/Stackedplot.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
arguments
1919
options.?mag.graphics.style.Stackedplot
20-
options.Charts (1, 1) mag.graphics.chart.Stackedplot
20+
options.Charts (1, :) mag.graphics.chart.Stackedplot
2121
options.LegendLocation (1, 1) string {mustBeMember(options.LegendLocation, ["north", "south", "east", "west"])} = "south"
2222
end
2323

@@ -53,7 +53,7 @@
5353

5454
if ~isempty(this.YLabels)
5555

56-
for i = 1:numel(axes)
56+
for i = 1:numel(this.YLabels)
5757
l(i) = ylabel(axes(i), this.YLabels(i));
5858
end
5959
end

tests/unit/visualize/chart/tStackedplot.m

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,87 @@
88

99
methods (Test)
1010

11+
% Test that stackedplot charts can view more than one line per
12+
% axis.
13+
function stackedplotWithMultipleLines(testCase)
14+
15+
% Set up.
16+
data = testCase.createTestDataWithEvents(SetDuration = false, SetEndTime = false);
17+
18+
chart1 = mag.graphics.chart.Stackedplot(YVariables = ["A", "B", "C"]);
19+
chart2 = mag.graphics.chart.Stackedplot(YVariables = ["C", "A", "B"]);
20+
21+
% Exercise.
22+
f = mag.graphics.visualize(data, mag.graphics.style.Stackedplot(Charts = [chart1, chart2]));
23+
testCase.addTeardown(@() close(f));
24+
25+
% Verify.
26+
% The chart should only return the main objects, but the figure
27+
% should also show two vertical lines per plot.
28+
testCase.assertTrue(isvalid(f), "Figure should be valid.");
29+
30+
tl = f.Children.Children(1);
31+
testCase.assertClass(tl, "matlab.graphics.layout.TiledChartLayout", "Child should be a tiled layout.");
32+
33+
axes = mag.test.getAllAxes(tl);
34+
graph = [axes.Children];
35+
36+
testCase.assertSize(graph, [2, 3], "Number of graphs should match expectation.");
37+
testCase.assertClass(graph, "matlab.graphics.chart.primitive.Line", "Graphs should be lines.");
38+
39+
testCase.verifyEqual(graph(1, 1).YData, data.B', "Graph data should match.");
40+
testCase.verifyEqual(graph(1, 2).YData, data.A', "Graph data should match.");
41+
testCase.verifyEqual(graph(1, 3).YData, data.C', "Graph data should match.");
42+
testCase.verifyEqual(graph(2, 1).YData, data.C', "Graph data should match.");
43+
testCase.verifyEqual(graph(2, 2).YData, data.B', "Graph data should match.");
44+
testCase.verifyEqual(graph(2, 3).YData, data.A', "Graph data should match.");
45+
end
46+
47+
% Test that multiple stackedplot can be independent of each other.
48+
function multipleIndependentStackedplots(testCase)
49+
50+
% Set up.
51+
data = testCase.createTestDataWithEvents(SetDuration = false, SetEndTime = false);
52+
53+
chart1 = mag.graphics.chart.Stackedplot(YVariables = ["A", "B", "C"]);
54+
chart2 = mag.graphics.chart.Stackedplot(YVariables = ["C", "A", "B"]);
55+
56+
% Exercise.
57+
f = mag.graphics.visualize(data, [mag.graphics.style.Stackedplot(Charts = chart1), mag.graphics.style.Stackedplot(Charts = chart2)]);
58+
testCase.addTeardown(@() close(f));
59+
60+
% Verify.
61+
% The chart should only return the main objects, but the figure
62+
% should also show two vertical lines per plot.
63+
testCase.assertTrue(isvalid(f), "Figure should be valid.");
64+
65+
tl1 = f.Children.Children(1);
66+
testCase.assertClass(tl1, "matlab.graphics.layout.TiledChartLayout", "Child should be a tiled layout.");
67+
68+
axes1 = mag.test.getAllAxes(tl1);
69+
graph1 = [axes1.Children];
70+
71+
testCase.assertSize(graph1, [1, 3], "Number of graphs should match expectation.");
72+
testCase.assertClass(graph1, "matlab.graphics.chart.primitive.Line", "Graphs should be lines.");
73+
74+
testCase.verifyEqual(graph1(1).YData, data.B', "Graph data should match.");
75+
testCase.verifyEqual(graph1(2).YData, data.A', "Graph data should match.");
76+
testCase.verifyEqual(graph1(3).YData, data.C', "Graph data should match.");
77+
78+
tl2 = f.Children.Children(3);
79+
testCase.assertClass(tl2, "matlab.graphics.layout.TiledChartLayout", "Child should be a tiled layout.");
80+
81+
axes2 = mag.test.getAllAxes(tl2);
82+
graph2 = [axes2.Children];
83+
84+
testCase.assertSize(graph2, [1, 3], "Number of graphs should match expectation.");
85+
testCase.assertClass(graph2, "matlab.graphics.chart.primitive.Line", "Graphs should be lines.");
86+
87+
testCase.verifyEqual(graph2(1).YData, data.C', "Graph data should match.");
88+
testCase.verifyEqual(graph2(2).YData, data.B', "Graph data should match.");
89+
testCase.verifyEqual(graph2(3).YData, data.A', "Graph data should match.");
90+
end
91+
1192
% Test that instantaneous events are correctly displayed on the
1293
% stackedplot.
1394
function instantaneousEvents(testCase)

0 commit comments

Comments
 (0)