Matlab中点击绘图空白区域触发取消选中线条的方法
解决Matlab绘图中曲线高亮后的取消选中问题
原代码存在的问题
- 每次触发曲线选中逻辑时,都会重复创建
text对象,导致界面上存在多个重叠的操作文本;且数据光标模式(datacursormode)会拦截鼠标事件,使得文本的ButtonDownFcn无法被触发。 - 未利用坐标轴的点击事件处理空白区域的取消操作,不符合“点击空白区域取消选中”的需求。
方案1:点击绘图空白区域取消选中
通过给坐标轴绑定ButtonDownFcn,实现点击非曲线区域时自动重置所有线条的样式。
修改后的完整代码
clear close all p(1) = plot(0:100, sin(0:100)); hold on p(2) = plot(0:100, cos(0:100)); legend('sin', 'cos') ylim([-2, 2]) % 获取当前坐标轴并绑定点击事件 ax = gca; set(ax, 'ButtonDownFcn', @unselect) % 配置数据光标模式 datacursormode on; dcmgr = datacursormode(gcf); set(dcmgr, 'UpdateFcn', @select) function output_txt = select(~, event_obj, ~) % 生成数据提示文本 pos = get(event_obj, 'Position'); output_txt = {... event_obj.Target.DisplayName... num2str(pos(1), 4)... num2str(pos(2), 4) ... }; % 重置所有曲线为半透明、细线条(跳过图例中的线条) all_lines = findall(gcf, 'Type', 'line'); set(all_lines, 'LineWidth', 1); for k = 1:numel(all_lines) if ~strcmp(all_lines(k).Parent.Type, 'legend') all_lines(k).Color = [all_lines(k).Color(1:3), 0.2]; end end % 高亮选中的曲线 event_obj.Target.LineWidth = 2; event_obj.Target.Color = [event_obj.Target.Color(1:3), 1]; end function unselect(~, ~) % 重置所有曲线为不透明、细线条(跳过图例中的线条) all_lines = findall(gcf, 'Type', 'line'); set(all_lines, 'LineWidth', 1); for k = 1:numel(all_lines) if ~strcmp(all_lines(k).Parent.Type, 'legend') all_lines(k).Color = [all_lines(k).Color(1:3), 1]; end end end
关键说明
- 坐标轴的
ButtonDownFcn会在点击空白区域(未触发数据光标事件的区域)时触发,自动调用取消选中函数。 - 增加了对图例线条的判断,避免图例样式被意外修改,不需要的话可以删除该判断逻辑。
方案2:使用固定文本按钮取消选中
如果偏好使用文本按钮的方式,需要将文本对象的创建放在主脚本中,确保它能正常接收点击事件。
修改后的完整代码
clear close all p(1) = plot(0:100, sin(0:100)); hold on p(2) = plot(0:100, cos(0:100)); legend('sin', 'cos') ylim([-2, 2]) % 创建固定的取消选中文本按钮,设置点击事件 t = text(90, -1.8, '取消选中', 'FontSize', 10, 'ButtonDownFcn', @unselect); set(t, 'HitTest', 'on') % 确保文本能捕获点击事件 % 配置数据光标模式 datacursormode on; dcmgr = datacursormode(gcf); set(dcmgr, 'UpdateFcn', @select) function output_txt = select(~, event_obj, ~) % 生成数据提示文本 pos = get(event_obj, 'Position'); output_txt = {... event_obj.Target.DisplayName... num2str(pos(1), 4)... num2str(pos(2), 4) ... }; % 重置所有曲线为半透明、细线条(跳过图例中的线条) all_lines = findall(gcf, 'Type', 'line'); set(all_lines, 'LineWidth', 1); for k = 1:numel(all_lines) if ~strcmp(all_lines(k).Parent.Type, 'legend') all_lines(k).Color = [all_lines(k).Color(1:3), 0.2]; end end % 高亮选中的曲线 event_obj.Target.LineWidth = 2; event_obj.Target.Color = [event_obj.Target.Color(1:3), 1]; end function unselect(~, ~) % 重置所有曲线为不透明、细线条(跳过图例中的线条) all_lines = findall(gcf, 'Type', 'line'); set(all_lines, 'LineWidth', 1); for k = 1:numel(all_lines) if ~strcmp(all_lines(k).Parent.Type, 'legend') all_lines(k).Color = [all_lines(k).Color(1:3), 1]; end end end
关键说明
- 文本对象仅创建一次,避免重复叠加。
- 设置
HitTest为on,确保文本可以正常接收点击事件,不会被数据光标模式拦截。 - 调整文本位置到绘图区域角落,避免遮挡曲线。
内容的提问来源于stack exchange,提问作者texnic
相关产品推荐
相关产品推荐

