如何删除Matlab图形上的单个点?最好通过 GUI
How to delete a single point on a Matlab figure? preferably by GUI
考虑以下情节:
我的数据点太密集了,我想隐藏或删除其中的一些点以使图表更清晰。如果不重新计算数据并重新绘制图形(这很耗时),我怎么能做到这一点?
我能想到的最 GUI 方式是使用 'Data Cursor' 工具选择点以查看其值,然后替换 XData 和 YData 属性这指向 NaN,在 'More Properties' 按钮处。
或者,您可以 alter the callback function of the 'Data Cursor' to do this for you (you can see 另一个示例)。
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.
创建图形后,右键单击图形中的工具提示之一并选择编辑文本更新函数。
选项 1
在打开的编辑器中,在末尾添加以下行:
event_obj.Target.XData(event_obj.Target.XData==pos(1)) = nan;
event_obj.Target.YData(event_obj.Target.YData==pos(2)) = nan;
为该函数指定一个有意义的名称,并将其另存为一个新的 .m 文件。
这是您应该得到的一个简单示例:
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;
现在,再次右键单击图中的工具提示之一并选择 Select 文本更新函数。在打开的浏览器中选择您刚刚保存的函数(这里是DeletePoint.m
)。
现在,每次使用 'Data Cursor' 工具点击一个点都会将其删除。但是,请记住,恢复点的唯一方法是重新创建图形,因为数据已从图形中删除(而不是从保存它的工作区中的变量中删除)。
选项 2
在打开的编辑器中,在末尾添加以下行:
% 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
其余的与选项1相同。这里的区别在于后一个函数会再次绘制具有相同属性的所有线,但没有您选择的点。通常,每次删除一个点时,数据光标会自动移动到下一个点(这就是为什么我们不能简单地删除这些点,它会启动一个删除整行的循环)。这里我们删除了整行,所以 Matlab 会在每次删除时发出警告:
Warning: Error while executing listener callback for MarkedClean event. Source has been deleted
为了避免这种情况,我添加了 warning('off')
和函数的末尾,但是您应该在使用数据游标工具后立即重新设置它们。
绘制未连接的点时,您可以将不需要的点的 XData
或 YData
(或两者)替换为 NaN
。对于带有线条的图表,这不起作用(它会产生不连续性),并且必须从数据向量中 删除 适当的点。我将在下面的示例中演示这是如何完成的:
出于演示目的,我假设您正在使用 .fig
文件,并且没有 plots/lines.
的句柄
让这是用于绘制图形的代码:
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;
然后,假设你加载了图并且它是当前图(gcf
),你可以这样做:
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
您可以使用您想要计算的任何逻辑ind2rem
,甚至可以手动指定它。
以上是在R2017a上测试的
最简单的方法:
- 单击按钮 "Brush/Select Data"
- Select 分
- 右击鼠标
- 选择"Remove"
这样既保留了线条的连续性,又不需要编码
考虑以下情节:
我的数据点太密集了,我想隐藏或删除其中的一些点以使图表更清晰。如果不重新计算数据并重新绘制图形(这很耗时),我怎么能做到这一点?
我能想到的最 GUI 方式是使用 'Data Cursor'
或者,您可以 alter the callback function of the 'Data Cursor' to do this for you (you can see
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.
创建图形后,右键单击图形中的工具提示之一并选择编辑文本更新函数。
选项 1
在打开的编辑器中,在末尾添加以下行:
event_obj.Target.XData(event_obj.Target.XData==pos(1)) = nan;
event_obj.Target.YData(event_obj.Target.YData==pos(2)) = nan;
为该函数指定一个有意义的名称,并将其另存为一个新的 .m 文件。
这是您应该得到的一个简单示例:
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;
现在,再次右键单击图中的工具提示之一并选择 Select 文本更新函数。在打开的浏览器中选择您刚刚保存的函数(这里是DeletePoint.m
)。
现在,每次使用 'Data Cursor' 工具点击一个点都会将其删除。但是,请记住,恢复点的唯一方法是重新创建图形,因为数据已从图形中删除(而不是从保存它的工作区中的变量中删除)。
选项 2
在打开的编辑器中,在末尾添加以下行:
% 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
其余的与选项1相同。这里的区别在于后一个函数会再次绘制具有相同属性的所有线,但没有您选择的点。通常,每次删除一个点时,数据光标会自动移动到下一个点(这就是为什么我们不能简单地删除这些点,它会启动一个删除整行的循环)。这里我们删除了整行,所以 Matlab 会在每次删除时发出警告:
Warning: Error while executing listener callback for MarkedClean event. Source has been deleted
为了避免这种情况,我添加了 warning('off')
和函数的末尾,但是您应该在使用数据游标工具后立即重新设置它们。
绘制未连接的点时,您可以将不需要的点的 XData
或 YData
(或两者)替换为 NaN
。对于带有线条的图表,这不起作用(它会产生不连续性),并且必须从数据向量中 删除 适当的点。我将在下面的示例中演示这是如何完成的:
出于演示目的,我假设您正在使用 .fig
文件,并且没有 plots/lines.
让这是用于绘制图形的代码:
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;
然后,假设你加载了图并且它是当前图(gcf
),你可以这样做:
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
您可以使用您想要计算的任何逻辑ind2rem
,甚至可以手动指定它。
以上是在R2017a上测试的
最简单的方法:
- 单击按钮 "Brush/Select Data"
- Select 分
- 右击鼠标
- 选择"Remove"
这样既保留了线条的连续性,又不需要编码