Generating Code from Plot

8 views (last 30 days)
Kody Spaberg
Kody Spaberg on 15 Apr 2017
Edited: DGM on 18 Oct 2024
I want to add a linear fit and show the function for a plot of data. So I plot my data, go to Tools, give it a linear fit and the equation, and generate my code. When I generate the code, the first issue I receive is that all the functions need an end. So I've added these. Then I tried changing the generic X1,Y1 variables to the variables I used in my plot. I finally got the code to run without issue but there is no resulting plot.
Here is my initial code:
figure(1)
% Plot
plot(Vm,Va_1,'o')
xlabel('Meter Reading Velocity (mph)')
ylabel('Actual Airspeed (m/s)')
title('Actual Airspeed vs Meter Reading Velocity')
hold off
And the generated code (I apologize for the length):
function createfigure2(Vm, Va_1)
%CREATEFIGURE2(X1, Y1)
% Vm: vector of x data
% Va_1: vector of y data
% Auto-generated by MATLAB on 15-Apr-2017 10:24:05
% Create figure
figure1 = figure;
% Create axes
axes1 = axes('Parent',figure1);
hold(axes1,'on');
% Create plot
plot1 = plot(Vm,Va_1,'DisplayName','data1','Marker','o','LineStyle','none');
% Get xdata from plot
xdata1 = get(plot1, 'xdata');
% Get ydata from plot
ydata1 = get(plot1, 'ydata');
% Make sure data are column vectors
xdata1 = xdata1(:);
ydata1 = ydata1(:);
% Remove NaN values and warn
nanMask1 = isnan(xdata1(:)) | isnan(ydata1(:));
if any(nanMask1)
warning('GeneratedCode:IgnoringNaNs', ...
'Data points with NaN coordinates will be ignored.');
xdata1(nanMask1) = [];
ydata1(nanMask1) = [];
end
% Find x values for plotting the fit based on xlim
axesLimits1 = xlim(axes1);
xplot1 = linspace(axesLimits1(1), axesLimits1(2));
% Preallocate for "Show equations" coefficients
coeffs1 = cell(1,1);
% Find coefficients for polynomial (order = 1)
fitResults1 = polyfit(xdata1,ydata1,1);
% Evaluate polynomial
yplot1 = polyval(fitResults1,xplot1);
% Save type of fit for "Show equations"
fittypesArray1(1) = 2;
% Save coefficients for "Show Equation"
coeffs1{1} = fitResults1;
% Plot the fit
fitLine1 = plot(xplot1,yplot1,'DisplayName',' linear','Tag','linear',...
'Parent',axes1,...
'Color',[0.929 0.694 0.125]);
% Set new line in proper position
setLineOrder(axes1,fitLine1,plot1);
% "Show equations" was selected
showEquations(fittypesArray1,coeffs1,2,axes1);
% Create xlabel
xlabel('Meter Reading Velocity (mph)');
% Create title
title('Actual Airspeed vs Meter Reading Velocity');
% Create ylabel
ylabel('Actual Airspeed (m/s)');
box(axes1,'on');
end
%-------------------------------------------------------------------------%
function setLineOrder(axesh1, newLine1, associatedLine1)
%SETLINEORDER(AXESH1,NEWLINE1,ASSOCIATEDLINE1)
% Set line order
% AXESH1: axes
% NEWLINE1: new line
% ASSOCIATEDLINE1: associated line
% Get the axes children
hChildren = get(axesh1,'Children');
% Remove the new line
hChildren(hChildren==newLine1) = [];
% Get the index to the associatedLine
lineIndex = find(hChildren==associatedLine1);
% Reorder lines so the new line appears with associated data
hNewChildren = [hChildren(1:lineIndex-1);newLine1;hChildren(lineIndex:end)];
% Set the children:
set(axesh1,'Children',hNewChildren);
end
%-------------------------------------------------------------------------%
function showEquations(fittypes1, coeffs1, digits1, axesh1)
%SHOWEQUATIONS(FITTYPES1,COEFFS1,DIGITS1,AXESH1)
% Show equations
% FITTYPES1: types of fits
% COEFFS1: coefficients
% DIGITS1: number of significant digits
% AXESH1: axes
n = length(fittypes1);
txt = cell(length(n + 1) ,1);
txt{1,:} = ' ';
for i = 1:n
txt{i + 1,:} = getEquationString(fittypes1(i),coeffs1{i},digits1,axesh1);
end
text(.05,.95,txt,'parent',axesh1, ...
'verticalalignment','top','units','normalized');
end
%-------------------------------------------------------------------------%
function [s1] = getEquationString(fittype1, coeffs1, digits1, axesh1)
%GETEQUATIONSTRING(FITTYPE1,COEFFS1,DIGITS1,AXESH1)
% Get show equation character vector
% FITTYPE1: type of fit
% COEFFS1: coefficients
% DIGITS1: number of significant digits
% AXESH1: axes
if isequal(fittype1, 0)
s1 = 'Cubic spline interpolant';
elseif isequal(fittype1, 1)
s1 = 'Shape-preserving interpolant';
else
op = '+-';
format1 = ['%s %0.',num2str(digits1),'g*x^{%s} %s'];
format2 = ['%s %0.',num2str(digits1),'g'];
xl = get(axesh1, 'xlim');
fit = fittype1 - 1;
s1 = sprintf('y =');
th = text(xl*[.95;.05],1,s1,'parent',axesh1, 'vis','off');
if abs(coeffs1(1) < 0)
s1 = [s1 ' -'];
end
for i = 1:fit
sl = length(s1);
if ~isequal(coeffs1(i),0) % if exactly zero, skip it
s1 = sprintf(format1,s1,abs(coeffs1(i)),num2str(fit+1-i), op((coeffs1(i+1)<0)+1));
end
if (i==fit) && ~isequal(coeffs1(i),0)
s1(end-5:end-2) = []; % change x^1 to x.
end
set(th,'string',s1);
et = get(th,'extent');
if et(1)+et(3) > xl(2)
s1 = [s1(1:sl) sprintf('\n ') s1(sl+1:end)];
end
end
if ~isequal(coeffs1(fit+1),0)
sl = length(s1);
s1 = sprintf(format2,s1,abs(coeffs1(fit+1)));
set(th,'string',s1);
et = get(th,'extent');
if et(1)+et(3) > xl(2)
s1 = [s1(1:sl) sprintf('\n ') s1(sl+1:end)];
end
end
delete(th);
% Delete last "+"
if isequal(s1(end),'+')
s1(end-1:end) = []; % There is always a space before the +.
end
if length(s1) == 3
s1 = sprintf(format2,s1,0);
end
end
end

Accepted Answer

Image Analyst
Image Analyst on 15 Apr 2017
Why even bother with all that generated code when you can simply call polyfit() and polyval() and get the straight line in a few lines of code? Attach your data if you need further help so we can read it in and help you with code.
  4 Comments
Saria Ahmad
Saria Ahmad on 4 Feb 2022
Hi, I want to generate code for the plots. I am trying to generate the left side plot. could you please suggest something?
rng(1) % For reproducibility
x = linspace(0,10,11);
y = sin(x);
%plotting
figure()
plot(x, y, "+", "MarkerFaceColor",'b')
title("Data Point Observations")
% xlim([0.0 1.0])
% ylim([-5.0 10])
hold off

Sign in to comment.

More Answers (1)

Maria Arabela
Maria Arabela on 18 Oct 2024
Edited: DGM on 18 Oct 2024
  2 Comments
DGM
DGM on 18 Oct 2024
Edited: DGM on 18 Oct 2024
This is not an answer, so it doesn't belong here as an answer.
This is not a question either, so I don't know what you expect to get from this.
If you want to ask a question, please post a new question using the "Ask" button at the top of the page.
DGM
DGM on 18 Oct 2024
Edited: DGM on 18 Oct 2024
I'm bored dead waiting for my boots to dry. We're squarely in the pre-weekend slowdown, so I'm going to pretend that this hypothetical question is old enough to tie its own shoes and I'll answer it like I'd answer any other vague dead question on a weekend.
I'm assuming the goal is to take this image of a plot and convert it to data, then obtain some sort of curve fit. If that's the case, then this is my typical answer for transcribing images of plots:
As a consequence:
% using the following FEX tools:
% https://www.mathworks.com/matlabcentral/fileexchange/72225-load-svg-into-your-matlab-code
% for the forum demo
unzip phone.svg.zip
% filename of manually-fit svg file
fname = 'phone.svg';
% data range from original image axis labels
% this is where the rectangle is drawn in the SVG
xrange = log10([10 80]); % because this is log-scale
yrange = [-2 1]; % because this is log-scale
% spline discretization parameter [0 1]
coarseness = 0.1; % 10 points per segment
% get plot box geometry
str = fileread(fname);
str = regexp(str,'((?<=<rect)(.*?)(?=\/>))','match');
pbx = regexp(str,'((?<=x=")(.*?)(?="))','match');
pby = regexp(str,'((?<=y=")(.*?)(?="))','match');
pbw = regexp(str,'((?<=width=")(.*?)(?="))','match');
pbh = regexp(str,'((?<=height=")(.*?)(?="))','match');
pbrect = [str2double(pbx{1}{1}) str2double(pby{1}{1}) ...
str2double(pbw{1}{1}) str2double(pbh{1}{1})];
% get coordinates representing the curve
S = loadsvg(fname,coarseness,false);
% if there are multiple paths you want to extract
% you'll need to do do the rescaling, etc for each element of S
for k = 1:numel(S) % there are multiple curves
x = S{k}(:,1);
y = S{k}(:,2);
% rescale to fit data range
x = xrange(1) + diff(xrange)*(x-pbrect(1))/pbrect(3);
y = yrange(1) + diff(yrange)*(pbrect(4) - (y-pbrect(2)))/pbrect(4);
x = 10.^x; % because this is logscale
y = 10.^y; % because this is logscale
% shove the prepared data back into S for later
S{k} = [x y];
end
% plot log-log space
for k = 1:numel(S)
x = S{k}(:,1);
y = S{k}(:,2);
loglog(x,y); hold on
end
grid on;
xlim(10.^xrange) % log scale
ylim(10.^yrange) % log scale
% fit using whatever model is relevant
% plot linear-linear space to emphasize curvature
F = cell(numel(S),1);
for k = 1:numel(S)
x = S{k}(:,1);
y = S{k}(:,2);
F{k} = fit(x,y,'rat12'); % this is just a guess
plot(F{k}); hold on
plot(x,y,'.','markersize',10)
end
Warning: Start point not provided, choosing random start point.
Warning: Start point not provided, choosing random start point.
grid on;
% use the fit models for whatever is needed
celldisp(F)
F{1} = General model Rat12: y(x) = (p1*x + p2) / (x^2 + q1*x + q2) Coefficients (with 95% confidence bounds): p1 = 0.5991 (0.4527, 0.7456) p2 = 103.2 (96.44, 109.9) q1 = -7.848 (-8.486, -7.209) q2 = 29.75 (25.78, 33.71) F{2} = General model Rat12: y(x) = (p1*x + p2) / (x^2 + q1*x + q2) Coefficients (with 95% confidence bounds): p1 = 7.314 (7.275, 7.354) p2 = -57.26 (-68.04, -46.47) q1 = -10.41 (-11.73, -9.089) q2 = 20.81 (18.58, 23.04)
If that's not what the question was, well then that's why written languages exist, now isn't it?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!