Skewed grid in plot

Is is possible to add a skewed grid in a plot? Consider the following image;

The grey axes are the normal axes ($$\mathbf{e}_1$$ and $$\mathbf{e}_2$$), the black axes are transformations $$\mathbf{e}'_1=2\mathbf{e}_1 - \mathbf{e}_2$$ and $$\mathbf{e}'_2=-\mathbf{e}_1 + \mathbf{e}_2$$ and the blue arrow is $$(1,1)$$ in the $$\mathbf{e}$$-base and $$(2,3)$$ in the $$\mathbf{e}'$$-base. I would like to insert a (red) grid that is “aligned” with the $$\mathbf{e}'$$-base, i.e. skewed so that one clearly sees that the blue arrow has coordinates $$(2,3)$$ in the transformed coordinate system. TIA.

MWE:

o = {0, 0};
e1 = {1, 0};
e2 = {0, 1};
e1p = 2 e1 - e2;
e2p = -e1 + e2;
v = {1, 1};
a0 = Graphics[{Blue, Arrow[{o, v}]}, GridLines -> Automatic, PlotRange -> {{-1.5, 4.5}, {-3, 2}}, Frame -> True];
a1 = Graphics[{Black, Opacity[.25], Arrow[{o, e1}], Arrow[{o, e2}]}];
a2 = Graphics[{Black, Arrow[{o, e1p}], Arrow[{o, e2p}]}];
k1 = Graphics[{Red, Arrow[{o, 2 e1p}]}];
k2 = Graphics[{{Red, Arrow[{2 e1p, 2 e1p + 3 e2p}]}, {Red, Arrow[{2 e1p, 2 e1p + 1 e2p}]}, {Red, Arrow[{2 e1p, 2 e1p + 2 e2p}]}}];
Show[a0, k1, k2, a1, a2]


The code might not be the best, improvements are most welcome!

With ColorFunction -> (White &)you can have a white background:

o = {0, 0};
e1 = {1, 0};
e2 = {0, 1};
e1p = 2 e1 - e2;
e2p = -e1 + e2;
v = {1, 1};
a0 = Graphics[{Blue, Arrow[{o, v}]}, GridLines -> Automatic,
PlotRange -> {{-1.5, 4.5}, {-3, 2}}, Frame -> True];
a1 = Graphics[{Black, Opacity[.25], Arrow[{o, e1}], Arrow[{o, e2}]}];
a2 = Graphics[{Black, Arrow[{o, e1p}], Arrow[{o, e2p}]}];
k1 = Graphics[{Red, Arrow[{o, 2 e1p}]}];
k2 = Graphics[{{Red, Arrow[{2 e1p, 2 e1p + 3 e2p}]}, {Red,
Arrow[{2 e1p, 2 e1p + 1 e2p}]}, {Red,
Arrow[{2 e1p, 2 e1p + 2 e2p}]}}];
pl = ContourPlot[.2, {x, -2, 4}, {y, -3, 2},
MeshFunctions -> {(e1p.{-#2, #1}) &, (e2p.{-#2, #1}) &},
Mesh -> {Range[-5, 5], Range[-5, 5]}, ColorFunction -> (White &)];
Show[pl, a0, k1, k2, a1, a2]


With ContourPlot[0.2,...,ColorFunction->Hue you can have any color you want by changing 0.2:

Using MeshStyleyou can specify the display of mesh lines. E.g.

pl = ContourPlot[.2, {x, -2, 4}, {y, -3, 2},
MeshFunctions -> {(e1p.{-#2, #1}) &, (e2p.{-#2, #1}) &},
Mesh -> {Range[-5, 5], Range[-5, 5]}, ColorFunction -> (White &),
MeshStyle -> {{Magenta, Opacity[0.5]}, {Green, Opacity[0.5]}}];
Show[pl, a0, k1, k2, a1, a2]


Another way is shifting the infiniteline InfiniteLine[{0, 0}, e1p] and InfiniteLine[{0, 0}, e2p]

o = {0, 0};
e1 = {1, 0};
e2 = {0, 1};
e1p = 2 e1 - e2;
e2p = -e1 + e2;
v = {1, 1};
a0 = Graphics[{Blue, Arrow[{o, v}]},
PlotRange -> {{-1.5, 4.5}, {-3, 2}}, Frame -> True];
a1 = Graphics[{Black, Opacity[.25], Arrow[{o, e1}], Arrow[{o, e2}]}];
a2 = Graphics[{Black, Arrow[{o, e1p}], Arrow[{o, e2p}]}];
k1 = Graphics[{Red, Arrow[{o, 2 e1p}]}];
k2 = Graphics[{{Red, Arrow[{2 e1p, 2 e1p + 3 e2p}]}, {Red,
Arrow[{2 e1p, 2 e1p + 1 e2p}]}, {Red,
Arrow[{2 e1p, 2 e1p + 2 e2p}]}}];
skew = Graphics[{Opacity[.5],
Table[{{Green, InfiniteLine[j*e2p, e1p]}, {Cyan,
InfiniteLine[j*e1p, e2p]}}, {j, -5, 5}]}];
Show[skew, a0, k1, k2, a1, a2, PlotRange -> {{-2, 4}, {-3, 2}}]


ParametricPlot also work.

skew2 = ParametricPlot[x*e1p + y*e2p, {x, -8, 8}, {y, -8, 8},
Mesh -> {Range[-8, 8]}, PlotStyle -> White, BoundaryStyle -> None,
Frame -> False, Axes -> False, PlotRange -> {{-2, 4}, {-3, 2}},
MeshStyle -> {Cyan, Green}]


We can use e1p and e2p to define two lists of transformation functions and use them to translate InfiniteLine[{o, e2p}] and InfiniteLine[{o, e2p}] to get the grid lines with desired slants.

trs1 = # e1p & /@ Range[-7, 7];
trs2 = # e2p & /@ Range[-7, 8];

Graphics[{{
Sequence @@ CurrentValue[{StyleDefinitions, "GraphicsGridLines"}],
Translate[InfiniteLine[{o, e2p}], #] & /@ trs1,
Translate[InfiniteLine[{o, e1p}], #] & /@ trs2},
Black, Opacity[.25], Arrow[{o, e1}], Arrow[{o, e2}],
Opacity[1], Arrow[{o, e1p}], Arrow[{o, e2p}],
Blue, Arrow[{o, v}],
Red, Arrow[{e1p, 2 e1p}],
Arrow[{2 e1p, 2 e1p + 3 e2p}]},
PlotRange -> {{-2, 5}, {-3, 2}}, Frame -> True, ImageSize -> Large]


• A fine solution (as always!). The code is bit difficult for me to understand, but that is a fault on my side(!). Would it be possible to change the ticks/tick labels also so they agree with the skewed lines?
– mf67
Mar 11, 2021 at 17:20
• @mf67, please see the updated version. If you want additional ticks on the left frame, try using FrameTicks -> {{Range[-3, 5, .5], Automatic},{ Automatic, Automatic}}.
– kglr
Mar 12, 2021 at 20:21
• Not sure I understand, but should not the 3 on the x-axis be 0 and 1 on the y-axis be 0 in the skewed system's tick labels?
– mf67
Mar 13, 2021 at 0:22
• @mf67, right,now i see what you mean. That's good new question.
– kglr
Mar 13, 2021 at 0:31
• Obviously there is a bug in Translate + InfiniteLine, because Translate[InfiniteLine[{o, e2p}], trs1] should wok too. Mar 13, 2021 at 0:51

Of course, we can do this with graphics primitives. However, the lazy way is to use ContourPlot, only for the sake of the Mesh. Here is your example:

a1 = Graphics[{Black, Opacity[.25], Arrow[{o, e1}], Arrow[{o, e2}]}];
a2 = Graphics[{Black, Arrow[{o, e1p}], Arrow[{o, e2p}]}];
k1 = Graphics[{Red, Arrow[{o, 2 e1p}]}];
k2 = Graphics[{{Red, Arrow[{2 e1p, 2 e1p + 3 e2p}]}, {Red,
Arrow[{2 e1p, 2 e1p + 1 e2p}]}, {Red,
Arrow[{2 e1p, 2 e1p + 2 e2p}]}}];
pl = ContourPlot[1, {x, -2, 4}, {y, -3, 2},
MeshFunctions -> {(e1p.{-#2, #1}) &, (e2p.{-#2, #1}) &},
Mesh -> {Range[-5, 5], Range[-5, 5]}];
Show[{pl, a0, k1, k2, a1, a2}, Axes -> True]


• Is there a way to control the yellow "paper" color and the color of the mesh?
– mf67
Mar 9, 2021 at 21:11