transforming coordinate system


I've got some data that roughly follows some f(x) . To now show the difference against that function, I'd like to transform the coordinate system, so that the f(x) line becomes the horizontal x-axis, and the (previously horizontal) y-grid lines become curves that are labelled on the right and left side of the diagram (like height lines on a map).

I looked at coord_trans , but that only allows to give single-parameter functions for x and y transformations; I'd like some way to specify eg. 1-exp(-x) should become the x-axis line, so the new y-coordinates depend on x as well.
The graph data (points and/or lines) and grid should get transformed as well, of course.

Is that already possible? Would it be enough to pass the x coordinate to the y transformer function as well to use it for coordinate translation?

Thank you for any help!

Could you please turn this into a self-contained reprex (short for reproducible example) or even a little diagram, since this question is more theoretical? It will help us help you if we can be sure we're all working with/looking at the same stuff.


If you've never heard of a reprex before, you might want to start by reading the help page. The reprex dos and don'ts are also useful.

What to do if you run into clipboard problems

If you run into problems with access to your clipboard, you can specify an outfile for the reprex, and then copy and paste the contents into the forum.

reprex::reprex(input = "fruits_stringdist.R", outfile = "")

For pointers specific to the community site, check out the reprex FAQ.

1 Like

Okay, here you are. I hope that helps. Sorry for the ugly code, I'm using R not often enough to remember all the details ;/

Given this data:


f <- function(x) { return (1-exp(-x/5)); }

data <- data.frame( x = seq(0, 20) )
data$y <- sapply(data$x, f) + rnorm(length(data$x), sd=0.1)

ggplot( data,
	   aes( x= x,
		   y= y)) +

I can easily plot normalized to f(x) via

ggplot( data, aes( x= x, y= y - f(x))) +

and now only quite a few details are missing, that I could try to fix up like this:

gridlines0 <- data.frame( x= 0:20, y=0-f(0:20))
gridlines1 <- data.frame( x= 0:20, y=1-f(0:20))
gridlines2 <- data.frame( x= 0:20, y=2-f(0:20))
gridlines05 <- data.frame( x= 0:20, y=0.5-f(0:20))

ggplot( data, aes(x= x, y= y-f(x))) +
scale_y_continuous(breaks = NULL)+
geom_line(data=gridlines0) + 
geom_line(data=gridlines1) + 
geom_line(data=gridlines2) + 
geom_line(data=gridlines05) + 
geom_text(data=gridlines0[1,], aes(label="0"), nudge_x=-1) +
geom_text(data=gridlines1[1,], aes(label="1"), nudge_x=-1) +
geom_text(data=gridlines2[1,], aes(label="2"), nudge_x=-1) +
geom_text(data=gridlines05[1,], aes(label="0.5"), nudge_x=-1) +

So, basically I'm transforming the coordinate system, with one axis depending on the location on the other axis (here Y depends on X). Now I'd like a) all the grid, grid labels, etc. to be correct without all that (now manual) stuff, and it would be more ideal if I could give a function of two arguments that returns two arguments (instead of now having cood_trans doing two functions of one argument each).

The short answer is “no” - it is not possible to transform coordinate systems in that way in ggplot2. I will not rule out that it is doable to write a Coord class that could perform this, but I think it is much more viable to simply subtract the function value from your data and plot the results. In the end you’d get the same plot but it would probably be easier for people to interpret compared to a plot with some strange coordinate transformation...


Hi Thomas,

well, only subtracting the f(x) value isn't enough - the grid doesn't show the absolute values anymore, the scaling isn't optimal (by default), etc. -- I need to manually override quite a lot of things. And if I'd like to transform both X and Y it's even harder.

My point is to enhance the difference between the function value from the model, and the really measured value, but to have the absolute Y values easily available, too.