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

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

Risposte (2)

Adam Danz
Adam Danz il 29 Giu 2018
Modificato: Adam Danz il 29 Giu 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 Commenti

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 helpful. Thanks again.
I copied your follow-up question here as a comment.
The code I shared above will do exactly what you seem to be asking. Have you tried it? Here's what you need to do...
Step 1) Of your 450 data points, get the index values of the porition you want to reflect and take that portion of the curve and put it in a new variable. Example
% let's sat your curve is named 'data'
idx = [250:500]; %points 200 to 500
importantPart = data(idx); %this is the part you want to reflect
Step 2) Follow my code above; and you don't need to calculate each point one my one. My code will reflect the entire segment all together. All you have to do is substitute your x, y, slope, intercept variables which you already have and then run the rest of my code. 'x' and 'y' should be column vectors. For example...
x = idx; %This will be your x values (*column vector*)
y = importantPart; %this is your y values (*column vector*)
slope = 39; %your slope
intercept = -20026; %your y-int
Now just run the rest of the code to reflect the line segment which produced (xFinal, yFinal).
Step 3) Replace the original data with the 'importantPart'.
data(idx) = importantPart;
I try to do what you said but I could not achieve it, I get some plot with first one here is my code and also my data set in excel file, I hope that I'm not causing too much trouble. Thank you so much.
if true
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;
% 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();
data(idx) = importantPart;
end
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.
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();

Accedi per commentare.

truckdriver
truckdriver il 30 Giu 2018
Modificato: truckdriver il 30 Giu 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 Commento

I moved the conversation to the comment section under my answer rather than starting a new answer which is really a question.

Accedi per commentare.

Categorie

Scopri di più su Graphics Performance in Centro assistenza e File Exchange

Prodotti

Release

R2016b

Richiesto:

il 29 Giu 2018

Commentato:

il 1 Lug 2018

Community Treasure Hunt

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

Start Hunting!

Translated by