Clickable Plot Where non-clicked lines go transparent?
5 次查看(过去 30 天)
显示 更早的评论
I have some plots that I want to be able to click on one or more lines and have all the other lines go semi-transparent while the clicked lines are brought to the front. I also want these lines to be able to be deselected so that I can go back to none of them being transparent
Dumbed down version of my code so far:
figure(1)
clf
p = panel();% create panel on the figure
p.pack(2, groupCount);% setup two rows and however many columns there are groups
for i = 1:length(data)
p(1, groupIdx(i)).select();%select the correct plot
plot(data(i).x1data, data(i).y1data, 'tag',sprintf(data(i).id)); %plot each line and give it a tag
p(2, groupIdx(i)).select();%select the correct plot
H1(i) = plot(data(i).x2data, data(i).y2data, 'tag',sprintf(data(i).id)); %plot each line and give it a tag
set(H1(i), 'ButtonDownFcn', {@LineSelected, H1(i)}); %make the line bold and at the front when it is clicked (from mathworks answer)
end
And then I got the following from this answer: https://www.mathworks.com/matlabcentral/answers/83231-how-to-use-the-mouse-to-select-and-identify-a-line-on-a-plot
function LineSelected(ObjectH, EventData, H)
set(ObjectH, 'LineWidth', 2.5); %make bold
set(H(H ~= ObjectH), 'LineWidth', 0.5);
uistack(ObjectH, 'top'); %bring it to the front
end
This lets me select one or more lines, and when I select them they are brought to the front and made bold, but since my plots are all kind of on top of each other it gets hard to see the data, especially bold. And on top of that, once a line is clicked it cannot be deselected, so it is bold until I re-run the script. So instead of being bold I want everything else to just go transparent, but I also want to be able to deselect the lines if needed.
0 个评论
回答(1 个)
Jan
2021-4-29
编辑:Jan
2021-4-29
To avoid setting the bolder linewidth, simply omit the change of the linewidth:
function LineSelected(ObjectH, EventData, H)
uistack(ObjectH, 'top'); %bring it to the front
end
Unfortunately there is no Alpha property for lines. So you either have to emulate the line objects by using patch objects, or you need another method to increase the visibility of the selected line: maybe some markers or by using dots for the other lines?
How do you select a line, which is covered by other initially?
What about using the 3rd dimension, to distribute the lines horizontally for a better overview:
function SelectorExample
X = rand(10, 100); % Ugly test data
FigH = figure;
Axes1H = subplot(1,2,1, ...
'Parent', FigH, 'NextPlot', 'add');
title(Axes1H, 'Data')
Axes2H = subplot(1,2,2, ...
'Parent', FigH, 'NextPlot', 'add');
title(Axes2H, 'For selection');
view(Axes2H, 3);
UD.Line1H = plot(Axes1H, X);
UD.Line2H = plot3(1:100, repmat(1:10, 100, 1), X, ...
'Parent', Axes2H);
set([UD.Line1H; UD.Line2H], 'ButtonDownFcn', {@SelectLine, FigH});
UD.Selected = [];
FigH.UserData = UD;
end
function SelectLine(LineH, EventData, FigH)
UD = FigH.UserData;
Index = find(LineH == UD.Line1H);
if isempty(Index)
Index = find(LineH == UD.Line2H);
end
if isequal(Index, UD.Selected) % Unselect:
UD.Selected = [];
UD.Line2H(Index).LineWidth = 0.5;
else
UD.Selected = Index;
set(UD.Line2H, 'LineWidth', 0.5);
set(UD.Line2H(Index), 'LineWidth', 2.5);
uistack(UD.Line2H(Index), 'top');
uistack(UD.Line1H(Index), 'top');
% Some blinking?!
for k = 1:5
set(UD.Line1H(Index), 'LineWidth', 3.5);
pause(0.1);
set(UD.Line1H(Index), 'LineWidth', 0.5);
pause(0.1);
end
end
FigH.UserData = UD;
end
You need to enable the 3D rotation in the right axes to get a proper view direction for an easier selection. Afterwards you have to deselect the rotation mode to be able to select the lines. This switching can be avoided, but this code is only a demonstration.
The code lets the line in the left diagram blink. Maybe this helps to see it. The main problem remains, that diagrams with a lot of equal curves are more or less impossible to undestand. Even transparency would not be a great help.
3 个评论
Jan
2021-4-30
编辑:Jan
2021-4-30
In your code "UD(:).Line2" is a comma separated list, but you need a vector. Simply include it in square brackets: [UD(:).Line2] .
The code gets much easier, if you store vectors in the scalar struct, instead of scalars as fields of a struct array:
UD(i).Line1
% ==>
UD.Line1(i)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Graphics Performance 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!