How do I extract data from the graph in this image?
119 views (last 30 days)
Show older comments
Hi,
I need to collect the data which is displayed in this image. I have to do this to quite a few images so I'm wondering if there is a way to it as quick and smoothly as possible?
I do have image processing toolbox but I'm very new to Mathworks so I would appreciate as much help as I could get.
Thanks!
6 Comments
Mathieu NOE
on 30 Jan 2024
that may help , but it's the method , you still have to work a little bit
it also depends if your pictures are all similar or not
DGM
on 30 Jan 2024
Edited: DGM
on 30 Jan 2024
Given the relatively low resolution for the number of datapoints, you can expect that the error will be significant. Consider that the image doesn't have enough resolution for the bar graph to be represented without aliasing, so the apparent x-spacing between points will not be periodic. The fact that it's not constant is purely an artifact of the use of an image as a lossy means of storing data.
Accepted Answer
DGM
on 30 Jan 2024
Edited: DGM
on 30 Jan 2024
The more I look at this graph, the worse it gets. At least it's a clean PNG, but it's small for what's represented, and there are no xticks and nothing is labeled. It's not clear what it represents, so it's hard to tell whether there's supposed to be a 1:1 relationship between the number and x-position of samples in the two series. If there was, then the aliasing has completely ruined it. There's simply not enough resolution to tell where half the vertices used to be in the lower series. Blindly sampling will just add another layer of aliasing.
I'm going to do this the hard way because I don't think there's an easy way. The result is questionable, though if all you need is the upper series, that's probably okay (any y-error being accepted). At any rate, it's probably a more exact representation of what's in the image than you'll get through other methods -- or at least there will be fewer artifacts of the image segmentation process being converted to "data".
I'm doing this the same way I always do it. The SVG is attached.
% using the following FEX tools:
% https://www.mathworks.com/matlabcentral/fileexchange/72225-load-svg-into-your-matlab-code
% filename of manually-fit svg file
fname = 'test.svg';
% data range from original image axis labels
% this is where the rectangle is drawn in the SVG
xrange = [1 250];
yrange = [-60 60];
% spline discretization parameter [0 1]
coarseness = 1;
% get plot box geometry
str = fileread(fname);
str = regexp(str,'((?<=<rect)(.*?)(?=\/>))','match');
pbx = regexp(str,'((?<=x=")(.*?)(?="))','match');
pby = regexp(str,'((?<=y=")(.*?)(?="))','match');
pbw = regexp(str,'((?<=width=")(.*?)(?="))','match');
pbh = regexp(str,'((?<=height=")(.*?)(?="))','match');
pbrect = [str2double(pbx{1}{1}) str2double(pby{1}{1}) ...
str2double(pbw{1}{1}) str2double(pbh{1}{1})];
% get coordinates representing the curve
S = loadsvg(fname,coarseness,false);
% if there are multiple paths you want to extract
% you'll need to do do the rescaling, etc for each element of S
for k = 1:numel(S) % there are multiple curves
x = S{k}(:,1);
y = S{k}(:,2);
% rescale to fit data range
x = xrange(1) + diff(xrange)*(x-pbrect(1))/pbrect(3);
y = yrange(1) + diff(yrange)*(pbrect(4) - (y-pbrect(2)))/pbrect(4);
% get rid of nonunique points
% this may or may not be needed depending on the shape
% of the curves and how they're to be processed
[x,idx,~] = unique(x,'stable');
y = y(idx);
% shove the prepared data back into S for later
S{k} = [x y];
end
% plot
for k = 1:numel(S)
x = S{k}(:,1);
y = S{k}(:,2);
plot(x,y); hold on
end
grid on;
xlim(xrange)
ylim(yrange)
Okay, so there's the data. Ignore the fact that I'm representing both as line plots. We don't know whether the x-position is supposed to be evenly spaced, or whether the samples of the two series are supposed to be aligned. If they are, then everything will have to be massaged back into shape. Good luck with that.
Now the big question is whether this is practical to apply to many images. I manually transcribed ~500 datapoints for this example. Unless you have more patience, the answer is obviously no.
4 Comments
DGM
on 4 Feb 2024
What error are you getting? The functions svgc() and svgl() should have come with loadsvg(). If you got loadsvg(), then you might need to make sure everything has been added to the path.
FWIW, (and I don't remember if I mentioned this in the thread I linked or if it was some other thread), none of the SVG import tools on the FEX actually provide comprehensive support for the format. This particular tool only supports path objects (polylines and splines), so I'm importing the rectangle object by parsing the file directly like a caveman. If you're trying to do something more elaborate, there may be hurdles to overcome.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!