How do I extract data from the graph in this image?

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

Sign in to comment.

Accepted Answer

DGM
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
Fredrik
Fredrik on 2 Feb 2024
Hi, thanks again for the help. I'm having some issues with running the code you wrote on other SVG's. If you don't mind me asking, what do I have to input after having loaded the svg, particularly in regards to svgc and svgl? Could I maybe see what you did in the example above to do it?
DGM
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.

Sign in to comment.

More Answers (0)

Tags

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!