Adding an image/chart as plot background

10 views (last 30 days)
I've created a scatter plot from the results of a cone penetration test and I the points to be representented on a roberston chart just as in the figure below but I don't just know how to go about. In summary this is what I need
Vs what I presently have
This is the chart I will like to have as background
Thanks in advance
  1 Comment
Jonas on 6 Dec 2022
can you give your data as attachment please, so we can plot the given data. your code so far would also be nice. do you have the lines of image 2 only as picture or also as data?

Sign in to comment.

Accepted Answer

DGM on 6 Dec 2022
Edited: DGM on 6 Dec 2022
Here's one cheap way. You'll have to crop the image down.
[inpict map] = imread('robertson_cropped.png');
inpict = ind2rgb(inpict,map); % this is an indexed image. it must be RGB
inpict = flipud(inpict); % need to flip the image
% some fake data
n = 50;
x = 9.9*rand(n,1)+0.1;
y = 999*rand(n,1);
% build the plot in log/log scale
scatter(x,y); hold on;
xlim([0.1 10]);
ylim([1 1000]);
% insert the image
hi = image(inpict,'xdata',[-1 1],'ydata',[0 3]);
uistack(hi,'down') % move it beneath the scatter plot
If you would rather have the Robertson chart constructed from clean line objects, you'll have to build it from primitives. I don't see any ready-made tools for doing that. I'm not sure how these curves would be described mathematically, but if that's not known, you can use one of these images as a template and just transcribe it like so:
For example, you could use the attached SVG file to get the curve data:
% using the following FEX tools:
% filename of manually-fit svg file
fname = 'robertsonchart.svg';
% data range from original image axis labels
% this is where the rectangle is drawn in the SVG
xrange = [-1 1];
yrange = [0 3]; % because this is semilog-scale
% spline discretization parameter [0 1]
coarseness = 0.01;
% get plot box geometry
str0 = fileread(fname);
str = regexp(str0,'((?<=<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 text locations (i used circles as markers)
str = regexp(str0,'((?<=<circle)(.*?)(?=\/>))','match');
cx = regexp(str,'((?<=cx=")(.*?)(?="))','match');
cy = regexp(str,'((?<=cy=")(.*?)(?="))','match');
cx = str2double([cx{:}]);
cy = str2double([cy{:}]);
% rescale to fit data range
cx = xrange(1) + diff(xrange)*(cx-pbrect(1))/pbrect(3);
cy = yrange(1) + diff(yrange)*(pbrect(4) - (cy-pbrect(2)))/pbrect(4);
cx = 10.^cx; % because this is logscale
cy = 10.^cy; % because this is logscale
% 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);
x = 10.^x; % because this is logscale
y = 10.^y; % because this is logscale
% shove the prepared data back into S for later
S{k} = [x y];
% plot each curve
for k = 1:numel(S)
x = S{k}(:,1);
y = S{k}(:,2);
hll = loglog(x,y); hold on
% add text labels
for k = 1:numel(cx)
ht = text(cx(k),cy(k),sprintf('%d',k));
grid on;
xlim(10.^xrange) % log scale
ylim(10.^yrange) % log scale
You could save the appropriate variables to a .mat file and then write a little function (attached) to generate the chart.
% some fake data
n = 50;
x = 9.9*rand(n,1)+0.1;
y = 999*rand(n,1);
% throw down the chart background
% build the plot in log/log scale
That looks a lot better. Feel free to change the line and text properties in robertsonchart.m.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!