If I create a new graphics device the user coordinates seem to define a (0,1) square but I can't make any marks because plot.new
hasn't been called yet:
> dev.new()
> par()$usr
[1] 0 1 0 1
> points(0.5, 0.5)
Error in plot.xy(xy.coords(x, y), type = type, ...) :
plot.new has not been called yet
Is there a simple way to turn this graphics device into a drawable canvas with user coordinates in (0,1),(0,1)?
I've tried simply plot.new()
but that sets up for an invisible blank chart with space for margins. The points (0,0) and (1,1) are not at the corners of the graphics device.
I think I need to set some of the margin parameters to c(0,0,0,0)
, but I'm not sure which ones and maybe there's a more direct way.
The end result should be a blank graphics window (or other device) such that points(0,0)
produces a dot at the bottom left (or precisely, just a quarter of a dot symbol) and points(1,1)
produces a quarter of a dot in the top right corner.
CodePudding user response:
par(mar = c(0, 0, 0, 0))
plot(NA, xlim=0:1, ylim=0:1, ann=FALSE, frame=FALSE,
xaxt="n", yaxt="n", xaxs="i", yaxs="i")
xlim=
andylim=
are needed because it cannot automatically determine the ranges based on the data;ann=
andframe=
make sure neither the axis labels nor the box/frame are shown;xaxt=
andyaxt=
remove the ticks; this might be slightly redundant, since even if plotted they will be outside the displayed region, but I thought I'd mention this in case you ever usepar(mar=..)
other than all-zeroes;xaxs=
andyaxs=
disables the 4% expansion that is the default of R's base plotting engine.
CodePudding user response:
The solution seems to be to set mar
to zeroes and specify "i"
for the xaxs
and yaxs
when setting up the plot;
> par(mar=c(0,0,0,0))
> x=0:1
> y=0:1
> plot(x,y, type="n", xaxs="i", yaxs="i")
>
> points(1,1,pch=19,cex=4)
>
> points(0,0,pch=19,cex=4)
Without setting xaxs
and yaxs
there's a tiny margin:
The difference between the default "r" style and the "i" style being:
Style ‘"r"’ (regular) first extends the data range by 4
percent at each end and then finds an axis with pretty labels
that fits within the extended range.
Style ‘"i"’ (internal) just finds an axis with pretty labels
that fits within the original data range.
which probably means this only works for "pretty" exact bounds like 0 and 1, but might fail if I want a coordinate system precisely between 3.245 and 93.1 on an axis... Although I've tried and I think that "pretty" consideration is purely to the labels - the axis limit is exact.