Sorry to nitpick on terminology here, but I need to correct the terminology so I can more easily give an answer that helps you:
A Gray code gives an absolute position in 1D. What's the equivalent for 2D?
Nope. Gray Coding is just a way to encode consecutive numbers as binary vectors. Just as writing down these numbers as "straight" binary numbers; or, really, any other way to write down as many binary vectors as you have values to encode.
What gives an absolute position is putting these binary vectors as black/white (or transparent/opaque, or whatever) on a strip or disk, and reading the vector you're currently at, and then reversing that mapping.
Gray Coding has exactly one advantage here: neighboring positions change in only one binary value. That's a big advantage, technically, because it eliminates a whole class of errors that happen on the boundaries of positions. But it's not necessary for positioning.
Now, one fundamental problems arises:
In an encoder disk or strip, there's the second dimension along which you can produce that binary vector. On a 2D surface, where do you put the extra dimension? That doesn't exist; you could only go into the third dimension, i.e., normal to the 2D surface you want to position on. But then you have no direction to look at the code optically.
So, that's where this concept fails. There cannot be an equivalent for optical positioning.
Thus, you need to come up with something else. You could, for example, just put QR codes (or similar square data codes, QR is certainly not the best choice here) with positions on a square grid, and read them. You'd need a 2D sensor (as opposed to the 1D sensor on a 1D code), and it would need to have a viewport that's large enough to find the closest "whole" 2D code to the position you're on, thus, at least twice the length in each direction.
So, while this isn't a Gray Code equivalent, the Digital Paper type of 2D surface covering that Dave Tweed's answer points you to is probably exactly what you are looking for. The Anoto implementation of that idea, using De Brujin sequences along rows and columns, and using displacement of a single dot relative to a grid to represent the resultant values, is quite frankly ingenious.