zlin
zlin

Reputation: 195

How to delete a single point on a Matlab figure? preferably by GUI

Consider the following plot:

plot

My data points are too dense, and I would like to hide or delete some of them points to make the chart clearer. How can I do this without without recomputing the data and re-plotting the figure (which is time-consuming)?

Upvotes: 1

Views: 10225

Answers (3)

zlin
zlin

Reputation: 195

The simplest way:

  1. Click button "Brush/Select Data"
  2. Select Points
  3. Right Click mouse
  4. Choose "Remove"

In this way, the line continuity is retained and no coding is needed.

Upvotes: 3

EBH
EBH

Reputation: 10450

The most GUI way I can think of is selecting the point using the 'Data Cursor' enter image description here tool to see what are its' values and then replace the XData and YData property of this point to NaN, at the 'More Properties' button.

Alternatively, you can alter the callback function of the 'Data Cursor' to do this for you (you can see here another example).

Check if the data points in your plot are a 'Scatter' graphic object, to do that type get(gca,'children') in the command window while the figure is chosen, and see if the first line of output is:
Scatter with properties:
if so, use option 1 below. If not, plot the data points and the lines as different objects, or use option 2 below.

After you create the figure, right click on one of the tooltips in the figure and choose Edit Text Update Function.

Option 1

In the editor that opens add the following lines at the end:

event_obj.Target.XData(event_obj.Target.XData==pos(1)) = nan;
event_obj.Target.YData(event_obj.Target.YData==pos(2)) = nan;

Give the function some meaningful name, and save it as a new .m file.

Here is a simple example of what you should get:

function output_txt = DeletePoint(obj,event_obj) % Give it some meaningful name
% Display the position of the data cursor
% obj          Currently not used (empty)
% event_obj    Handle to event object
% output_txt   Data cursor text string (string or cell array of strings).

pos = get(event_obj,'Position');
output_txt = {['X: ',num2str(pos(1),4)],...
    ['Y: ',num2str(pos(2),4)]};

% If there is a Z-coordinate in the position, display it as well
if length(pos) > 2
    output_txt{end+1} = ['Z: ',num2str(pos(3),4)];
end

% The lines you add:
event_obj.Target.XData(event_obj.Target.XData==pos(1)) = nan;
event_obj.Target.YData(event_obj.Target.YData==pos(2)) = nan;

Now, right click again on one of the tooltips in the figure and choose Select Text Update Function. In the browser that opens choose the function you just saved (here, it's DeletePoint.m).

Now, every click on a point using the 'Data Cursor' tool will delete it. However, keep in mind that the only way to restore the points is to newly create the figure, as the data is deleted from the figure (but not from the variables in the workspace that hold it).

Option 2

In the editor that opens add the following lines at the end:

% The lines you add:
props = {'Color',...
    'LineStyle',...
    'LineWidth',...
    'Marker',...
    'MarkerSize',...
    'MarkerEdgeColor',...
    'MarkerFaceColor'};
line_props = get(event_obj.Target,props);
newX = event_obj.Target.XData;
newY = event_obj.Target.YData;
newX(newX==pos(1)) = [];
newY(newY==pos(2)) = [];
new_line = line(newX,newY);
set(new_line,props,line_props);
delete(event_obj.Target)
warning('off') % after you finish removing points, type warning('on') in the command window

All the rest is as in option 1. The difference here is that the latter function draws all the line again with the same properties, but without the point you selected. Normally, each time you delete a point the Data cursor automatically moves to the next point (and this is why we can't simply delete the points, it will initiate a loop that deletes the whole line). Here we delete the whole line, so Matlab issues a warning on every deletion:

Warning: Error while executing listener callback for MarkedClean event. Source has been deleted

To avoid that I added warning('off') and the end of the function, but you should set them on again as soon as you finish with the Data cursor tool.

Upvotes: 1

Dev-iL
Dev-iL

Reputation: 24179

When plotting unconnected points, you can replace either the XData or YData (or both) of the points you don't want by NaN. For charts with lines, this doesn't work (it creates discontinuities), and the appropriate points must be removed from the data vectors. I'll demonstrate how this is done in the example below:

For the purposes of demonstration, I shall assume that you're working with a .fig file, and have no handles to the plots/lines.

Let this be the code used to plot a figure:

x = [0:0.05:0.9, 1:0.01:1.09, 1.1:0.1:pi/2];
figure(); plot(x,sin(x),'-+',x,sin(x-0.02),'-^',x,sin(x-0.04),'-s'); grid minor;

Then, assuming you loaded the figure and it is the current figure (gcf), you can do:

function q45177572
%% Find handles:
hL = findobj(gcf,'Type','Line');
%% Choose which indices to remove, and remove...
for ind1 = 1:numel(hL)
  % (Option 1) Keeping every other datapoint:
  ind2rem = 1:2:numel(hL(ind1).XData);
  % (Option 2) Removing points in a certain interval:
  ind2rem = hL(ind1).XData > 1 & hL(ind1).XData < 1.05;
  % (Option 3) Manual (watch out for indices out of bounds!)
  ind2rem = [1 3 20:23 30];
  % (Option 4) ...

  % Finally, delete the points:
  hL(ind1).XData(ind2rem) = [];
  hL(ind1).YData(ind2rem) = [];
end

You can use whichever logic you want to compute ind2rem, or even specify it manually.

The above was tested on R2017a.

Upvotes: 2

Related Questions