How to interactively select different plots in a figure and merge them together?

조회 수: 3 (최근 30일)
Lorenzo Melito 2024년 3월 11일
댓글: Lorenzo Melito 2024년 3월 26일
I have several little lines of plot that represent portions of particle trajectories: each of such "pieces" are described by x- and y-coordinates. I am looking for a way to produce a figure of all these pieces, click on each of the pieces that visually belong to the same trajectory, and merge their x- and y- coordinates into a single array.
Here is a very simple example:
x = linspace(0,pi,100);
y = sin(x); z = cos(x/2);
x1 = x(1:12); y1 = y(1:12);
x2 = x(19:25); y2 = y(19:25);
x3 = x(45:67); y3 = y(45:67);
x4 = x(90:end); y4 = y(90:end);
x5 = x(4:19); y5 = z(4:19);
x6 = x(40:88); y6 = z(40:88);
plot(x1,y1,'b'); grid on; hold on
plot(x2,y2,'b')
plot(x3,y3,'b')
plot(x4,y4,'b')
plot(x5,y5,'r')
plot(x6,y6,'r')
From here, I need to click on all the blue plots (which belong to the "sine" trajectory) or red plots (which belong to the "cosine" trajectory), collect their coordinates and save them into a single array (for a future reconstruction of the original trajectory or whatever).
Searching a bit through MATLAB Answers, I came across this question that explains how to extract data from MATLAB figures. This is quite similar to what I need; but instead of by inspecting properties, I need to do it interactively by clicking on each plot, one after the other, and saving in the workspace the XData and YData of all plots I have clicked. In this sense, the concept should be similar to what ginput does with plot coordinates.

댓글을 달려면 로그인하십시오.

채택된 답변

Sachin Lodhi 2024년 3월 18일
Hi Lorenzo, from what I understand, you want to join together line segments on a figure in a way that you can control as you go. Below, I've put together a piece of code to help you start with this. Remember, this is just a basic setup for merging lines, and you might need to tweak it a bit to make it work just right for you.
function merge_plot_pieces
% Sample plot pieces
x = linspace(0,pi,100);
y = sin(x); z = cos(x/2);
% Define segments
segments = { x(1:12), y(1:12); x(19:25), y(19:25); x(45:67), y(45:67); x(90:end), y(90:end); x(4:19), z(4:19); x(40:88), z(40:88)};
colors = ['b', 'b', 'b', 'b', 'r', 'r'];
% Initialize global variables to store merged coordinates and last color
global mergedX;
global mergedY;
global lastColor;
mergedX = [];
mergedY = [];
lastColor = ''; % Empty indicates no color selected yet
% Plot segments
fig = figure; hold on; grid on;
for i = 1:size(segments, 1)
h = plot(segments{i,1}, segments{i,2}, colors(i));
set(h, 'ButtonDownFcn', @plotClicked, 'UserData', colors(i)); % Store color in UserData
end
% Set up a key press function to reset the merging process
set(fig, 'KeyPressFcn', @resetMerging);
end
function plotClicked(src, ~)
% This function is called when a plot segment is clicked
global mergedX;
global mergedY;
global lastColor;
currentColor = src.UserData; % Get the color of the clicked plot from UserData
% Check if the color matches the last clicked color or if it's the first click
if isempty(lastColor) || strcmp(lastColor, currentColor)
% Append clicked segment data to global variables
mergedX = [mergedX, src.XData];
mergedY = [mergedY, src.YData];
lastColor = currentColor; % Update lastColor
% Plot the merged trajectory
plot(mergedX, mergedY, currentColor, 'LineWidth', 2, 'Tag', 'mergedTrajectory');
legend off
else
% If the colors don't match, do not merge and optionally alert the user
disp('Cannot merge: Selected segment is of a different color.');
end
end
function resetMerging(~, ~)
% This function resets the merging process to allow starting with a new color without clearing the last merged trajectory
global mergedX;
global mergedY;
global lastColor;
% Reset the global variables without clearing the last merged trajectory
mergedX = [];
mergedY = [];
lastColor = '';
disp('Merging process reset. You can now start merging a new color.');
end
I hope this helps.
댓글 수: 3이전 댓글 1개 표시이전 댓글 1개 숨기기
Sachin Lodhi 2024년 3월 26일
To save the merged trajectories (mergedX and mergedY) in the MATLAB workspace from within the function, you need to use the 'assignin' function. The 'assignin' function allows you to assign a value to a variable in a specified workspace, which in your case would be the 'base' workspace (MATLAB's main workspace).
You can modify the plotClicked and resetMergign function in the following way -
function plotClicked(src, ~)
global mergedX;
global mergedY;
global lastColor;
currentColor = src.UserData; % Get the color of the clicked plot from UserData
if isempty(lastColor) || strcmp(lastColor, currentColor)
mergedX = [mergedX, src.XData];
mergedY = [mergedY, src.YData];
lastColor = currentColor;
plot(mergedX, mergedY, currentColor, 'LineWidth', 2, 'Tag', 'mergedTrajectory');
legend off
% Save to base workspace
assignin('base', 'mergedX', mergedX);
assignin('base', 'mergedY', mergedY);
assignin('base', 'lastColor', lastColor);
else
disp('Cannot merge: Selected segment is of a different color.');
end
end
function resetMerging(~, ~)
global mergedX;
global mergedY;
global lastColor;
mergedX = [];
mergedY = [];
lastColor = '';
% Save the reset state to base workspace
assignin('base', 'mergedX', mergedX);
assignin('base', 'mergedY', mergedY);
assignin('base', 'lastColor', lastColor);
disp('Merging process reset. You can now start merging a new color.');
end
Lorenzo Melito 2024년 3월 26일
@Sachin Lodhi, again thank you very much for your kind help! assignin was just the missing piece I needed.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Polar Plots에 대해 자세히 알아보기

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by