Drawing a rectangle over existing plot

122 Ansichten (letzte 30 Tage)
gummiyummi
gummiyummi am 28 Jul. 2020
I have a subplot in Matlab with two plots. (first picture) I want to draw boxes as seen in the second picture, for specific xvalue ranges. I tried annotation however it does not span all plots. Anybody able to help me?
  3 Kommentare
gummiyummi
gummiyummi am 31 Jul. 2020
Sorry, I didn't put enough detail about what I had tried....
My problem is the dimension [ ] for each annotation. Since, my rectangle is supposed to envelope a specific x value and +- 5 seconds, I do not know how to format that as a varying dimension
Adam Danz
Adam Danz am 31 Jul. 2020
Bearbeitet: Adam Danz am 4 Aug. 2020
That's a clearer problem; and a tough one.
The annotation function has been around for a long time and many people have requested that the function accept location values in data-units rather than normalized figure units. Obviously these wishes have never been granted.
See answer for a cleaner solution.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Adam Danz
Adam Danz am 31 Jul. 2020
Bearbeitet: Adam Danz am 3 Aug. 2020
To use an annotation object in the way you're describing, you'd need to convert the data units, which are relative to the axes, to normalized figure units. Though this is possible, it often leads to headaches since a bunch of minor details turn out to be important such as setting axis limit and figure resizing.
The cleaner approach is to highlight the sections within the axes using the original data units.
Here's a demo that you can apply to your project.
% Set up a figure with two subplots and identical x-axes
figure()
sp(1) = subplot(2,1,1);
x = 0:10:1400;
y = randi(400,size(x))+200;
plot(x, y, '.')
xlim([0,1400])
ylim([200,600])
sp(2) = subplot(2,1,2);
y2 = rand(size(x))*5-1;
plot(x,y2,'.')
linkaxes(sp, 'x') % Link the x axes
ylim([-1,4])
% Define rectangle center and +/-d
rectCnt = 590;
rectDelta = 25; % +/-25 from center
% Draw rectangle in upper axes
rectX = rectCnt + rectDelta*[-1,1];
rectY = ylim([sp(1)]);
pch1 = patch(sp(1), rectX([1,2,2,1]), rectY([1 1 2 2]), 'r', ...
'EdgeColor', 'none', 'FaceAlpha', 0.3); % FaceAlpha controls transparency
% Copy rectangle to 2nd axes and adjust y limits
pch2 = copyobj(pch1, sp(2));
rectY2 = ylim(sp(2));
pch2.YData = rectY2([1 1 2 2]);
If you plan on moving the rectangles around, you can link their XData properties so you only need to change one of them and the other one will follow.
linkprop([pch1, pch2], 'XData')
% now slide the bar to the right by 100 units
% and see what happens...
pch1.XData = pch1.XData + 100;
  15 Kommentare
Carlos Quispe Galdos
Carlos Quispe Galdos am 30 Jul. 2022
Excellent Adam! Thank you
Afiq Azaibi
Afiq Azaibi am 17 Mär. 2023
Bearbeitet: Afiq Azaibi am 17 Mär. 2023
In addition to Adam's solution, starting in R2023a you can use the xregion or yregion functions:
% Set up a figure with two subplots and identical x-axes
figure()
sp(1) = subplot(2,1,1);
x = 0:10:1400;
y = randi(400,size(x))+200;
plot(x, y, '.')
xlim([0,1400])
ylim([200,600])
sp(2) = subplot(2,1,2);
y2 = rand(size(x))*5-1;
plot(x,y2,'.')
linkaxes(sp, 'x') % Link the x axes
ylim([-1,4]);
xregion(sp(1), 565, 615, 'FaceColor', 'r');
xregion(sp(2), 565, 615, 'FaceColor', 'r');
You can also set the EdgeColor properties to emphasize the edges but the default EdgeColor is 'none'.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Vahidreza Jahanmard
Vahidreza Jahanmard am 14 Nov. 2023
To plot the rectangles, you can use this:
% do all your plots
annotation('rectangle',[x y w h]);
for x, y, w, and h, you can plot one time and set the place of the rectangle manually and copy the position to your code

Community Treasure Hunt

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

Start Hunting!

Translated by