extracting table data from a plot picture question
4 ビュー (過去 30 日間)
古いコメントを表示
Hello,I have many plots like this in the data sheet.
there is a java tools which manually allow to extract the data of each plot.
Is the a way in matlab to do it?
Thanks.
0 件のコメント
回答 (2 件)
DGM
2024 年 9 月 28 日
編集済み: DGM
2024 年 9 月 29 日
It depends how the images vary and what you expect. This would normally be my recommendation:
If the curves are all non-overlapping and equivalently-spaced saturated colors, you can get a jagged approximation instead:
inpict = imread('image.png');
% box extents in data coordinates
xrange = [2 9];
yrange = [-20 0];
% find the colored lines
hsvpict = rgb2hsv(inpict);
hlim = [0.9 0.1; 0.23 0.43; 0.5667 0.7667];
slim = 0.3;
llim = 0.4;
tracemask = false([size(inpict,1:2) 3]);
slmask = (hsvpict(:,:,2)>=slim) & (hsvpict(:,:,3)>=llim);
for c = 1:3
if hlim(c,1) > hlim(c,2)
mask = (hsvpict(:,:,1)>=hlim(c,1) | hsvpict(:,:,1)<=hlim(c,2));
else
mask = (hsvpict(:,:,1)>=hlim(c,1) & hsvpict(:,:,1)<=hlim(c,2));
end
mask = mask & slmask;
% some filtering may be required to fix holes
% or to otherwise make sure each line is contiguous
%mask = imclose(mask,ones(20,1));
% select the largest blob
mask = bwareafilt(mask,1);
% reduce the blob to a central line
tracemask(:,:,c) = bwskel(mask);
end
imshow(double(tracemask))
% find plot box
% V < 0.5 excludes everything remotely close
% to the saturated edges of the RGB cube
lim = [0 0.5];
mask = (hsvpict(:,:,3)>=lim(1) & hsvpict(:,:,3)<=lim(2));
% get rid of small speckles, and select only long straight lines
mask = bwareaopen(mask,100);
mask = imopen(mask,ones(50,1)) | imopen(mask,ones(1,50));
mask = bwskel(mask);
%imshow(mask) % this won't show up on the forum anyway
% box extents in image coordinates
% this will be inaccurate if the plot box has
% external ticks or other spur artifacts on its exterior
[x1 x2] = bounds(find(any(mask,1)));
[y1 y2] = bounds(find(any(mask,2)));
% get all three curves
% i'm using a cell array, since the vector pairs
% are not necessarily the same length
% if you need them to be represented on a common abcissa
% you can use interp1() to do the interpolation
xdata = cell(3,1);
ydata = cell(3,1);
for c = 1:3
trace = tracemask(:,:,c);
% convert the trace to xy data
[y0 x0] = find(trace,1); % find initial point
B = bwtraceboundary(trace,[y0 x0],'E'); % [y x]
x = B(:,2);
y = B(:,1);
% rescale the trace to data coordinates
x = xrange(1) + diff(xrange)*(x-x1)/(x2-x1);
y = yrange(1) + diff(yrange)*((y2-y1) - (y-y1))/(y2-y1);
% get rid of nonunique points
% this restricts us to capturing curves which
% represent single-valued functions of x
[x,idx,~] = unique(x);
y = y(idx);
xdata{c} = x;
ydata{c} = y;
end
% plot
plot(xdata{1},ydata{1},'r'); grid on; hold on
plot(xdata{2},ydata{2},'g')
plot(xdata{3},ydata{3},'b')
xlim(xrange)
ylim(yrange)
0 件のコメント
Vandit
2024 年 9 月 28 日
You can get the data from a plot by accessing the XData and YData properties from each Line object in the axes. Please refer to the following MATLAB Answers post which resolves the similar query:
Additionally, you can refer to the video tutorial below, which shows how to extract data from plotted figures:
Hope this helps.
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Polar Plots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!