Clickable Plot Where non-clicked lines go transparent?

6 views (last 30 days)
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
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.

Answers (1)

Jan
Jan on 29 Apr 2021
Edited: Jan on 29 Apr 2021
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 Comments
Amanda Beatty
Amanda Beatty on 29 Apr 2021
Okay, I gave it my best shot of copying what you did and altering it to fit my needs. The code is a ways above my competency level, though. And the fact that my plotting is in a for loop is really making me struggle.
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
UD(i).Line1 = 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
UD(i).Line2 = plot(data(i).x2data, data(i).y2data, 'tag',sprintf(data(i).id)); %plot each line and give it a tag
set([UD(i).Line1; UD(i).Line2], 'ButtonDownFcn', {@SelectLine, Fig1});; %make the line bold and at the front when it is clicked (from mathworks answer)
UD(i).Selected = [];
end
FigH.UserData = UD;
function SelectLine(LineH, EventData, FigH)
UD = FigH.UserData;
for i=1:length(UD) %pretty sure this is wrong?
if ~isempty(find(LineH == UD(i).Line2))
Index=i; %find the index of the selected line
end
end
if isempty(Index)
for i=1:length(UD)
if ~isempty(find(LineH == UD(i).Line1))
Index=i; %find the index of the selected line
end
end
end
if isequal(Index, UD(Index).Line2) % Unselect:
UD(Index).Selected = [];
UD(Index).Line2.LineWidth = 0.5;
else
UD(Index).Selected = Index;
set(UD(:).Line2, 'LineWidth', 1/72);
set(UD(Index).Line2, 'LineWidth', 0.5);
set(UD(:).Line1, 'LineWidth', 1/72);
set(UD(Index).Line1, 'LineWidth', 0.5);
uistack(UD(Index).Line2, 'top');
uistack(UD(Index).Line1, 'top');
end
FigH.UserData = UD;
end
It, of course, errors out "Error while evaluating ButtonDownFcn" on this line:
set(UD(:).Line2, 'LineWidth', 1/72);
Jan
Jan on 30 Apr 2021
Edited: Jan on 30 Apr 2021
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)

Sign in to comment.

Categories

Find more on Line Plots in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!