I have a plottable function whose normalized domain is [0,1] and whose normalized range is [-1,1]. I also have two TikZ coordinates, (BOTLEFT)
and (TOPRIGHT)
defining the bottom left and top right of a bounding box where I would like the plot to appear.
I would like to effect a skewless, rotationless affine linear coordinate transform such that the plot domain/range is fitted exactly to the bounding box. That is, each point (x,y) is mapped to
(x,y) → (BOTLEFT)
+ ((TOPRIGHT)
- (BOTLEFT)
) · ((x,y) - (0,-1)) ÷ ((1,1) - (0,-1))
For example, the sine wave
\draw[domain = 0:1, samples = 256] plot (\x,{sin(\x*4*pi r)});
when subject to the transform, should fit exactly inside the bounding box
\draw[red] (-2,5) rectangle (1,8);
if (BOTLEFT)
is (-2,5) and (TOPRIGHT)
is (1,8).
TikZ supports the xshift
, yshift
, xscale
and yscale
properties to implement the coordinate transform. However, computing the xscale
and yscale
properties manually using coordinate arithmetic would appear to require isolating the x and y components of (BOTLEFT)
and (TOPRIGHT)
. I know this can be done (e.g., by the let
directive):
\coordinate (BOTLEFT) at ({-.2},.5);
\coordinate (TOPRIGHT) at (.1,.8);
\draw let
\p1 = (BOTLEFT),
\p2 = (TOPRIGHT) in [domain = 0:1, samples = 256,
xshift = \x1,
xscale = (\x2 - \x1)\pts,
yshift = (\y1 + (\y2 - \y1)/2),
yscale = ((\y2 - \y1)/2)\pts
] plot (\x,{sin(\x*4*pi r)});
\draw[red] (BOTLEFT) rectangle (TOPRIGHT);
where \pts
is a macro that expands to *<constant>
to convert from pts to the scaling units for the figure, but this seems extremely messy, especially for TikZ/PGF. I can't help but think that TikZ has some kind of built-in to handle this. It would be especially useful if the transform could be scope
-d, too. That is,
\begin{scope}[<set transform here>]
\draw[domain = 0:1, samples = 256] plot (\x,{sin(\x*4*pi r)});
<more commands in same coordinate frame>
...
\end{scope}
Is there a more elegant way of handling this in TikZ, or am I stuck with hacking the coordinate math in this way?
Clarification #1
The coordinates (BOTLEFT)
and (TOPRIGHT)
are computed using expressions involving node anchor points, not numeric literals as in the example.
\pgfpointanchor{BOTLEFT}{center}
will let\pgf@x
and\pgf@y
be the coordinate of the lower-left corner. That way you can isolate x and y.