2
votes

I would like to create a simple scatter plot in R or MATLAB involving two variables $x$ and $y$ which have errors associated with them, $\epsilon_x$ and $\epsilon_y$.

Instead of adding error-bars, however, I was hoping to create a "shaded box" around each $(x,y)$ pair where the height of the box ranges from ($y - \epsilon_y$) to ($y + \epsilon_y$) and the width of the box ranges from ($x - \epsilon_y$) to ($x + \epsilon_y$) .

Is this possible in R or MATLAB? If so, what package or code can I use to generate these plots. Ideally, I would like the package to also support asymmetric error bounds.

5

5 Answers

4
votes

You could do it in matlab by creating the following function:

function errorBox(x,y,epsx,epsy)
    %# make sure inputs are all column vectors
    x = x(:); y = y(:); epsx = epsx(:); epsy = epsy(:);

    %# define the corner points of the error boxes
    errBoxX = [x-epsx, x-epsx, x+epsx, x+epsx];
    errBoxY = [y-epsy, y+epsy, y+epsy, y-epsy];

    %# plot the transparant errorboxes
    fill(errBoxX',errBoxY','b','FaceAlpha',0.3,'EdgeAlpha',0)
end

x, y, epsx and epsy can all be vectors.

Example:

x = randn(1,5); y = randn(1,5);
epsx = rand(1,5)/5;
epsy = rand(1,5)/5;

plot(x,y,'rx')
hold on
errorBox(x,y,epsx,epsy)

Result:

1
votes

It's probably easier using the ggplot2. First create some data:

set.seed(1)
dd = data.frame(x = 1:5, eps_x = rnorm(5, 0, 0.1), y = rnorm(5), eps_y = rnorm(5, 0, 0.1))

##Save space later    
dd$xmin = dd$x - dd$eps_x
dd$xmax = dd$x + dd$eps_x
dd$ymin = dd$y - dd$eps_y
dd$ymax = dd$y + dd$eps_y

Then use the rectangle geom in ggplot2:

library(ggplot2)
ggplot(dd) + 
     geom_rect(aes( xmax = xmax, xmin=xmin, ymin=ymin, ymax = ymax))

gives the first plot. Of course, you don't need to use ggplot2, to get something similar in base graphics, try:

plot(0, 0, xlim=c(0.5, 5.5), ylim=c(-1, 1), type="n")
for(i in 1:nrow(dd)){
    d = dd[i,]
    polygon(c(d$xmin, d$xmax, d$xmax, d$xmin), c(d$ymin, d$ymin, d$ymax,d$ymax), col="grey80")
}

to get the second plot.

ggplot2 graph

Base graphics

1
votes

Here's how to do it using Matlab (with asymmetric intervals). Converting to symmetric ones should be trivial.

%# define some random data
x = rand(5,1)*10;y = rand(5,1)*10;
%# ex, ey have two columns for lower/upper bounds
ex = abs(randn(5,2))*0.3;ey=abs(randn(5,2));

%# create vertices, faces, for patches
vertx =  bsxfun(@minus,y,ey(:,[1 2 2 1]))';
verty =  bsxfun(@minus,y,ey(:,[1 1 2 2]))';
vertices = [vertx(:),verty(:)];
faces = bsxfun(@plus,[1 2 3 4],(0:4:(length(x)-1)*4)');

%# create patch
patch(struct('faces',faces,'vertices',vertices),'FaceColor',[0.5 0.5 0.5]);

%# add "centers" - note, the intervals are asymmetric
hold on, plot(x,y,'oy','MarkerFaceColor','r')

enter image description here

0
votes

It's simple with the ggplot2 package in R.

# An example data frame
dat <- data.frame(x = 1:5, y = 5:1, ex = (1:5)/10, ey = (5:1)/10)

# Plot
library(ggplot2)
ggplot(dat) +
  geom_rect(aes(xmin = x - ex, xmax = x + ex, ymin = y - ey, ymax = y + ey), 
            fill = "grey") +
  geom_point(aes(x = x, y = y))

In the aes function inside geom_rect the size of the rectangle is defined by ex and ey around x and y.

enter image description here

0
votes

Here's a MATLAB answer:

x = randn(1,5); y = 3-2*x + randn(1,5);
ex = (.1+rand(1,5))/5; ey = (.2+rand(1,5))/3;
plot(x,y,'ro')
patch([x-ex;x+ex;x+ex;x-ex],[y-ey;y-ey;y+ey;y+ey],[.9 .9 .9],'facealpha',.2,'linestyle','none')