# How to find tangent line of curve

30 views (last 30 days)
Vivianne on 17 Nov 2022
Commented: Star Strider on 18 Nov 2022
Hi guys, I'm new to matlab and I was trying to create a code that generates a graph with the tangent line of temperature by time. The data is a file with the temperature values and the transfer function. If anyone can help me that would be great.
I would have to generate a graph similar to this one:
% FOPDT (First order lag plus time delay)
y=yy; % temperature values y(t)
plot(y)

Image Analyst on 18 Nov 2022
Edited: Image Analyst on 18 Nov 2022
Do you have any data? What I'd do is to scan your data vector fitting the values within a certain window width to a quadratic. From the coefficients of the quadratic you can get the slope at the point at the center of the sliding window. Then knowing the slope you can use the point-slope formula for a line, and the desired length of the line to get the endpoints of a line segment tangent to your curve at that point. Upload a vector of your data values in a .mat or text file if you need more help.
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:
[EDIT] Seems like you're having trouble, so here is a demo:
fontSize = 12
fontSize = 12
x = linspace(0, 12, 1000);
deltax = x(2) - x(1)
deltax = 0.0120
period = 3;
y = sin(2 * pi * x / period);
plot(x, y, 'b-', 'LineWidth', 4);
grid on;
xlabel('x', 'FontSize', fontSize);
ylabel('y', 'FontSize', fontSize);
windowWidth = 51; % An odd number
halfWindowWidth = floor(windowWidth/2)
halfWindowWidth = 25
for k = halfWindowWidth + 1 : 66 : numel(x) - halfWindowWidth
thisSectionX = x(k-halfWindowWidth : k + halfWindowWidth);
thisSectionY = y(k-halfWindowWidth : k + halfWindowWidth);
% Fit to a quadratic or cubic. y = c(1) * x^2 + c(2) * x + c(3)
coefficients = polyfit(thisSectionX, thisSectionY, 2);
xCenter = thisSectionX(halfWindowWidth + 1);
yCenter = thisSectionY(halfWindowWidth + 1);
slope = 2 * coefficients(1) * xCenter + coefficients(2);
% (y - yCenter) = (x - xCenter) * slope.
% y = (x - xCenter) * slope + yCenter.
segmentLength = 2;
% Get the endpoints of the tangent line segment.
x1 = xCenter - halfWindowWidth * deltax;
x2 = xCenter + halfWindowWidth * deltax;
y1 = (x1 - xCenter) * slope + yCenter;
y2 = (x2 - xCenter) * slope + yCenter;
hold on;
% Plot line segment in red.
plot([x1, x2], [y1, y2], 'r.-', 'LineWidth', 2, 'MarkerSize', 20);
% Plot center point of line segment at a cyan dot.
plot(xCenter, yCenter, 'c.', 'MarkerSize', 20);
end
Image Analyst on 18 Nov 2022
Edited: Image Analyst on 18 Nov 2022
fontSize = 20;
s = struct with fields:
yy: [1000×1 double]
y = s.yy;
x = linspace(0, 20, length(y));
deltax = x(2) - x(1)
deltax = 0.0200
plot(x, y, 'b-', 'LineWidth', 4);
grid on;
xlabel('x', 'FontSize', fontSize);
ylabel('y', 'FontSize', fontSize);
windowWidth = 251; % An odd number
halfWindowWidth = floor(windowWidth/2)
halfWindowWidth = 125
% Find the index where x = 7
k = find(x >= 7, 1, 'first');
thisSectionX = x(k-halfWindowWidth : k + halfWindowWidth);
thisSectionY = y(k-halfWindowWidth : k + halfWindowWidth);
% Fit to a quadratic or cubic. y = c(1) * x^2 + c(2) * x + c(3)
coefficients = polyfit(thisSectionX, thisSectionY, 2);
xCenter = thisSectionX(halfWindowWidth + 1);
yCenter = thisSectionY(halfWindowWidth + 1);
slope = 2 * coefficients(1) * xCenter + coefficients(2);
% (y - yCenter) = (x - xCenter) * slope.
% y = (x - xCenter) * slope + yCenter.
segmentLength = 2;
% Get the endpoints of the tangent line segment.
x1 = xCenter - halfWindowWidth * deltax;
x2 = xCenter + halfWindowWidth * deltax;
y1 = (x1 - xCenter) * slope + yCenter;
y2 = (x2 - xCenter) * slope + yCenter;
% Plot line segment in red.
hold on;
plot([x1, x2], [y1, y2], 'r.-', 'LineWidth', 2, 'MarkerSize', 20);
% Plot center point of line segment at a cyan dot.
plot(xCenter, yCenter, 'c.', 'MarkerSize', 20);
But the data does not look like what your desired data should look like. I think you posted different data.
You might also like to fit it to an exponential, or sigmoid. See attached demos.

Star Strider on 18 Nov 2022
That plot actually looks familiar!
See: How to draw a tangent line on a curve for one approach. (That result used the inflection point of the curve to draw the tangent, so the code is slightly diffenent than the code here.)
I chose a ‘yy’ value of 50 here simply to demonstrate the code. Change the value of ‘select_yy’ to choose a different point. (There are no inflection points here that I can see, although I did not analyse the data carefully to see if one exists.) There is also no associated time vector, so I created one.
Try this —
yy = LD.yy;
Fs = 1; % Sampling Frequency
L = numel(yy);
t = linspace(0, L-1, L).'/Fs; % Time Vector
select_yy = 50; % Delect 'yy' Value At Which To Draw Tangent
idxr = find(diff(sign(yy-select_yy)))+(-1:1); % Index Range
t_yy50 = interp1(yy(idxr), t(idxr), 50) % Associated Time Value
t_yy50 = 162.3340
dyydt50 = interp1(t, dyydt, t_yy50) % Numerical Derivative At Associated Time
dyydt50 = 0.2336
y_intcpt = select_yy - dyydt50*t_yy50 % Line Y-Intercept
y_intcpt = 12.0714
figure
plot(t, yy, 'DisplayName','Data')
yl = ylim;
hold on
plot(t_yy50, select_yy, '.r', 'DisplayName','Tangent Point')
plot(t, dyydt50*t+y_intcpt, '-r', 'DisplayName','Tangent Line')
hold off
ylim(yl)
grid
legend('Location','best')
Make appropriate changes to get the desired result.
.
##### 2 CommentsShowHide 1 older comment
Star Strider on 18 Nov 2022
That was a different problem. (I remember it, because my code in the Answer I quoted generated that same plot.) I have no idea what the time vector is here because that was not stated. There just needs to be one.