I have a simple program to do the following.:
- Create a scatter plot of X and Y data.
- Highlight 3 points and fit a straight line through them. The user should be able to click on the figure and select any three points he or she wants to fit a line through.
- Calculate the X intercept of the fitted line.
I'm trying to do this using object oriented programming and hence have a simple data object which has these properties:
- X data
- Y data
- Number of points used for doing the line fit (3 in this case)
- Inital input of the interpolation (fit) points mentioned in 3
- X intercept (this is calculated in the constructor function using the inital fit points).
I can update the figure to display the latest 3 points selected and show the line fitted thorugh them, but my object (or instance of the object) does not get updated in the workspace with the latest interpolation points and the X interecept for the line fitted using those points.
Here is my object class definition:
classdef data_object properties x_data y_data num_points_linear_fit interp_points x_intercept end methods function new_data_object = data_object(x_data, y_data, num_points_linear_fit, interp_points) if nargin == 4 new_data_object.x_data = x_data; new_data_object.y_data = y_data; new_data_object.num_points_linear_fit = num_points_linear_fit; new_data_object.interp_points = interp_points; new_data_object.x_intercept = calc_x_intercept(new_data_object); end end function calculated_x_intercept = calc_x_intercept(obj) p = polyfit(obj.interp_points(:, 1), obj.interp_points(:, 2), 1); calculated_x_intercept = -p(2)/p(1); end function obj = graphical_interface(obj) X = obj.x_data; Y = obj.y_data; xy = obj.interp_points; num_fit_points = obj.num_points_linear_fit; num_data_points = numel(X); f = figure; hold on; box on points = gobjects(num_data_points, 1); for I = 1:num_data_points points(I) = plot(X(I), Y(I), 'bo', 'MarkerSize', 13); end; clear I ax = gca; set(f, 'HitTest', 'on') set(ax, 'HitTest', 'on') set(points,'ButtonDownFcn',@(src,eventdata)getpoints(src, eventdata, obj),... 'PickableParts','all') pp1 = plot(xy(:, 1), xy(:, 2), 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); p = polyfit(xy(:, 1), xy(:, 2), 1); temp = min(xy(:, 1)) : 0.01 : max(xy(:, 1)); pp2 = plot(temp, polyval(p, temp), 'r'); function getpoints(src, ~,~) cp_x = get(src, 'xdata'); cp_y = get(src, 'ydata'); xy = [[cp_x, cp_y]; xy]; if size(xy, 1) > num_fit_points xy = xy(1:num_fit_points, :); end delete(pp1) pp1 = plot(xy(:, 1), xy(:, 2), 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); if size(xy, 1) > 2 p = polyfit(xy(:, 1), xy(:, 2), 1); obj.interp_points = xy; obj.x_intercept = -p(2)/p(1); temp = min(xy(:, 1)) : 0.01 : max(xy(:, 1)); if isempty(pp2) pp2 = plot(temp, polyval(p, temp), 'r'); set(pp2, 'HitTest', 'off') else delete(pp2) pp2 = plot(temp, polyval(p, temp), 'r'); set(pp2, 'HitTest', 'off') end end end end endend
This is how I call it to test:
X = (1:10)';Y = rand(10, 1);interp_points = [X([3, 4, 5]), Y([3, 4, 5])];num_points_linear_fit = 3;a = data_object(X, Y, num_points_linear_fit, interp_points);graphical_interface(a);
I need my interpolation points and X intercept to update with every click (when new interpolation points are selected).
Any help would be greatly appreciated!
PS the 'interpolation points' should be called 'fit points'. Sorry for the confusion.
Thanks,
K
Best Answer