How to interactively select different plots in a figure and merge them together?
1 次查看(过去 30 天)
显示 更早的评论
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.
0 个评论
采纳的回答
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 个评论
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
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Annotations 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!