-5

I want to understand how plot() exactly work under the hood. But it eventually depends on C to make the actual plots.

R> plot
function (x, y, ...)
UseMethod("plot")
<bytecode: 0x7f9c23a7d6f0>
<environment: namespace:base>
R> plot.xy
function (xy, type, pch = par("pch"), lty = par("lty"), col = par("col"),
    bg = NA, cex = 1, lwd = par("lwd"), ...)
invisible(.External.graphics(C_plotXY, xy, type, pch, lty, col,
    bg, cex, lwd, ...))
<bytecode: 0x7f90f80ef3b0>
<environment: namespace:graphics>

Can anybody provide a translation (automated is preferred, but I understand there may not be one, if so, manually translated code for an example like plot(1:10, 1:10) is also OK) to the R language so that the points/axis/labels, etc., are plotted one by one (and how the positions are computed) so that I can see how plot() works under the hood?

user1424739
  • 11,937
  • 17
  • 63
  • 152
  • 1
    I don't know what you mean. usemethod doesn't mean it is written in C for each method but means it directs to S3 methods dispatch. That being said, with the base plots, you can perfectly draw each things separately. The syntax isn't modern at all though so it can be ugly. In particular, plot(...,type="n") permits you initialization with various parameters like xlim,ylim, main,... and then you can draw whatever you want – Arnaud Feldmann Aug 14 '21 at 11:54
  • You can check (that's just an example not a perfect model) what i've done with my package https://github.com/InseeFr/disaggR/blob/master/R/plot.R to make diverse plot methods for the objects in my package. base graphics allows you to do pretty much anything but it won't produce beautiful code (i personally dislike using graphical parameters with stupid side effects when everything in modern R is functional) – Arnaud Feldmann Aug 14 '21 at 11:58
  • @ArnaudFeldmann Could you make the simplest R code as an answer that just does the work of `plot(1:10, 1:10)`, yet does the calculation of the positions of all the objects (e.g., points, axis, ticks, labels) to plot and plot the objects one by one? – user1424739 Aug 14 '21 at 12:02
  • 2
    I'll just mention that it's a little bit annoying to spend effort on writing an answer that attempts to address the question as written to be told "that's not what I meant, forget it" – Ben Bolker Aug 14 '21 at 12:11

1 Answers1

0
#margins parameters
mar_save <- par("mar")
par(mar=c(2, 2.3, 0, 0))

#plot windows and initialisation
xmin <- -1
xmax <- 11
ymin <- 0
ymax <- 10
plot(x = c(xmin,xmax), y = c(ymin,ymax),
     xlim = c(xmin,xmax),
     ylim = c(ymin,ymax),
     type = "n",
     xaxs = "i", xaxt = "n",
     yaxs = "i", yaxt = "n")

# axes labels
title(xlab = "xlab", line= 0.8, cex.lab=0.8)
title(ylab = "ylab", line= 1.3, cex.lab=0.8)

#draws points
points(1:10,1:10)

#draws grid
grid(nx = NULL,ny=NULL,col = "grey")

#draws axes with ticks
axis(side = 1L, labels=NA, tick = TRUE)
axis(side = 2L, labels=NA, tick = TRUE)

#draws some y numbers on the ticks
axis(side = 2L, tick = FALSE, line=-0.5, cex.axis=0.7)

#resets margins
par(mar=mar_save)
Arnaud Feldmann
  • 761
  • 5
  • 17
  • 2
    this breaks down the plotting process one level; however, to fully answer the question (computing positions of titles, axis labels, ticks, etc., etc.) you would have to dig into and/or rewrite the guts of `axis`, `grid`, `title`, etc. ... – Ben Bolker Aug 14 '21 at 12:38
  • Of `points()`, are there more basic R commands that draw each point individually? If this can be updated, it will be great. – user1424739 Aug 14 '21 at 12:41
  • 1
    @BenBolker What I had understood from the question is that the asker mainly wanted to be able to draw "custom" things. That's why I answered that. – Arnaud Feldmann Aug 14 '21 at 12:42
  • 1
    @user1424739, you can see for yourself (following the same logic as in my now-deleted answer) that `points()` calls `points.default()` which calls `plot.xy()` ... which calls `External.graphics(C_plotXY,...)`. Still not sure what you want. You could use a `for` loop to call `points()` on individual points rather than the entire vector (e.g. `points(x[i], y[i])`. The actual conversion of user coordinates to graphics device coordinates is done [here](https://github.com/wch/r-source/blob/6e61247f042985d5cb9f09034cb9e694a69082e0/src/library/graphics/src/plot.c#L1625). – Ben Bolker Aug 14 '21 at 12:51
  • So, there is not a more basic command to just draw a single point on a plot in R? With the knowledge that I look for, I want to have a fine control of a plot at an R level but not at a C level. – user1424739 Aug 14 '21 at 13:00
  • 1
    To draw a single point on a plot, e.g. `x <- 5; y <- 3; points(x,y)`. `points()` is vectorized, but you can use length-1 vectors if you like (R doesn't have scalar types, only length-1 vectors). – Ben Bolker Aug 14 '21 at 13:07