How can I reflect a part of a plot on a vector?

39 views (last 30 days)
I import a set of data from excel and I plot it on Matlab with no codes buth only plot(data
). I want to reflect only a part of plot not whole plot and the part that I want to reflect is right bottom part and reflect it on the vector y=39x-20026 after refliction I want to keep reflected version and delete the original part? thanks in advanced

Answers (2)

Adam Danz
Adam Danz on 29 Jun 2018
Edited: Adam Danz on 29 Jun 2018
This should get you started.
The first step is to define what you mean by "right bottom". For example, if you want to consider the data that spans from x=300 to x=500 and you want to throw out the rest, then do that by
mainData = data(300:500);
The second step is to reflect the 'mainData' about the line y=39x-20026 where the slope is 39 and intercept is -20026. There's more than one way to do that. Here is a demo that does the following:
  • determine where each point will cross the reflection line
  • rotate each point about reflection line
Note that you may run into problems if your reflection line is exactly vertical (ie, your slope is inf). In that case the solution is even easier than this one.
% Fake Data
x = [6 8 9 9 11]';
y = [ 10 11 12 13 14]';
slope = 0.5;
intercept = 12;
% Calculate slope and y-int of line perpendicular to reflection line
perpSlope = -1/slope;
yInt = y - perpSlope.*x;
% Find where each point (x,y) crosses the reflection line
% These should all lie on the reflection line
xintersect = (yInt-intercept)/(slope-perpSlope);
yintersect = slope*xintersect + intercept;
% Shift each (x,y) point to the origin and rotate 180 deg
% more info: http://math.sci.ccny.cuny.edu/document/show/2685
xs = x - xintersect;
ys = y - yintersect;
xr = xs * cos(pi) - ys * sin(pi);
yr = xs * sin(pi) + ys * cos(pi);
%shift back to original positions, but reflected.
xFinal = xr + xintersect;
yFinal = yr + yintersect;
% Plot the data
figure
plot(x,y, 'm-o', 'DisplayName', 'OriginalData')
hold on
plot(xintersect,yintersect, 'mx', 'DisplayName', 'cross point')
plot(xFinal, yFinal, 'r-o', 'DisplayName', 'ReflectedData')
axis equal
rh = refline(slope, intercept);
rh.DisplayName = 'ReflectionLine';
legend()
Hopefully you can follow the demo and adapt your code as needed. That was fun, thanks.
  4 Comments
Adam Danz
Adam Danz on 1 Jul 2018
Edited: Adam Danz on 1 Jul 2018
Hi Ozan, I just downloaded your data and my algorithm works if you fix some of your errors I've listed below. However, I'm not sure if this is what you really want and I'll discuss that at the end of this comment.
  1. Some of the values in your excel file are stored as text so make sure you're importing all of the values correctly (you might already be doing it correctly but you should check).
  2. Your "if true" is useless. True will always be true. This isn't harming your code, it's just a useless line. So you can get rid of "if true" and the "end".
  3. As I mentioned, x and y need to be COLUMN VECTORS not row vectors. To convert between row and column use this x = x';
  4. You're extracting the 'imporantPart' correctly and you're rotating it correctly (well done). But when you plot it, you're only plotting that 'importantPart'. At the end of your code, you put the importantPart back into you data but you do this after you've plotted it! So you need to removed all of your code following the xFinal and yFinal calculations and replace it with this:
% Update your (x,y) values
originalX = 1:length(data);
newX = originalX;
newX(idx) = xFinal; %your new x values over the 'importantPart' segment
newData = data;
newData(idx) = yFinal; %your 'data' with the updated segment
% Plot results
figure
plot(originalX, data, 'b-', 'LineWidth', 4, 'DisplayName', 'Original data')
hold on
plot(newX, newData, 'b:', 'LineWidth', 3, 'DisplayName', 'Rotated Data')
rh = refline(slope, intercept);
rh.DisplayName = 'ReflectionLine';
rh.Color = 'm';
legend();
Which will produced this plot:
In that plot, the 'important part' of your curve is perfectly reflected about the reference line. The reason it doesn't look like a mirror image reflection is because the aspect ratios of the x and y axes aren't equal. Your y axis is much larger than your x axis. If you use "axis equal" it would be a true reflection but your data will be so squished that you won't be able to see it. My rotation method would only work if your x and y axes have the same units and aspect ratio and I didn't realize the difference until I got ahold of your data.
truckdriver
truckdriver on 1 Jul 2018
I try to what you suggest but I keep getting error like this In an assignment A(:) = B, the number of elements in A and B must be the same.
Error in reflection (line 26) newX(idx) = xFinal; %your new x values over the 'importantPart' segment I could not figure out what my mistake is and I changed code like below, I also tried insert code before xFinal and yFinal line but it did not worked either. By the way thank you so much for your time and insterest.
idx=[257:512];
importantPart=data(idx);
x=idx;
y=importantPart;
slope=39;
intercept=-20026;
% Calculate slope and y-int of line perpendicular to reflection line
perpSlope = -1/slope;
yInt = y - perpSlope.*x;
% Find where each point (x,y) crosses the reflection line
% These should all lie on the reflection line
xintersect = (yInt-intercept)/(slope-perpSlope);
yintersect = slope*xintersect + intercept;
% Shift each (x,y) point to the origin and rotate 180 deg
% more info: http://math.sci.ccny.cuny.edu/document/show/2685
xs = x - xintersect;
ys = y - yintersect;
xr = xs * cos(pi) - ys * sin(pi);
yr = xs * sin(pi) + ys * cos(pi);
%shift back to original positions, but reflected.
xFinal = xr + xintersect;
yFinal = yr + yintersect;
% Update your (x,y) values
originalX = 1:length(data);
newX = originalX;
newX(idx) = xFinal; %your new x values over the 'importantPart' segment
newData = data;
newData(idx) = yFinal; %your 'data' with the updated segment
% Plot results
figure
plot(originalX, data, 'b-', 'LineWidth', 4, 'DisplayName', 'Original data')
hold on
plot(newX, newData, 'b:', 'LineWidth', 3, 'DisplayName', 'Rotated Data')
rh = refline(slope, intercept);
rh.DisplayName = 'ReflectionLine';
rh.Color = 'm';
legend();

Sign in to comment.


truckdriver
truckdriver on 30 Jun 2018
Edited: truckdriver on 30 Jun 2018
Thank you for your answer but I think I could not express myself in question. I want to keep the rest of plot but reflect only the part that shown in picture. I have 450 data point therefore I don't think that I can reflect all point by one by. If there is another way to do that, it will be very helpfull. Thanks again.
  1 Comment
Adam Danz
Adam Danz on 1 Jul 2018
I moved the conversation to the comment section under my answer rather than starting a new answer which is really a question.

Sign in to comment.

Products


Release

R2016b

Community Treasure Hunt

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

Start Hunting!