# TikZ: different x, y scales but so that shapes maintain their aspects

I have some old pstricks code which I'm re-doing with TikZ. In my current picture, the x and y scales are different:

\begin{tikzpicture}[xscale=1.8,yscale=4]


However, this has the problem that circles are drawn as ellipses, being stretched more in the y direction. I've also tried

\begin{tikzpicture}[x=1.8cm,y=4cm]


but this has the same effect of stretching circles into ellipses.

So is there any way of scaling coordinates only in TikZ, which doesn't affect the object shapes?

I have discovered the solution as follows

\draw (1,1) circle(0.1cm);


does the job. I had been using

\draw (1,1) circle(0.1);


which picks up the individual scalings.

• There is no difference with my answer then. :-) Apr 12 '13 at 14:28
• This is because TikZ (and PGF) handle dimensions differently from dimensionless expressions. Dimensionless expressions are multipliers for the current x and y vectors (as relevant) whereas dimensions are taken to mean what they say. So radius=0.1cm means just that, whereas radius=0.1 means "set the x radius to 0.1 times the x vector and the y radius to 0.1 times the y vector". Apr 12 '13 at 14:38
• Attaching a metric unit in expressions should be avoided except for line width that we seldom change when scaling. Global scaling becomes cumbersome if we attach the metric unit for every length. For example (2,2) circle (1) is much better than (2cm,2cm) circle (1cm), but \draw[line width=2pt] is acceptable in most case. Apr 12 '13 at 15:40

PSTricks uses \psrunit when drawing \pscircle.

\documentclass[tikz,border=12pt]{standalone}

\newlength\runit
\runit=1cm

\begin{document}
\begin{tikzpicture}[x=3cm,y=2cm]
\draw (-2,-2) rectangle (2,2);
\end{tikzpicture}
\end{document}


Note: declaring the radial unit globally gives you an advantage where you can change all the unit of circle radii in one place.

We can also declare a new key so that we can access this radial unit easier.

\documentclass[tikz,border=12pt]{standalone}

\makeatletter
\newlength\tikz@runit
\tikzset{
r/.code=\pgfmathsetlength\tikz@runit{#1},
r=+1cm, % setting a default value
}
\makeatother

\begin{document}
\begin{tikzpicture}[x=3cm,y=2cm]
\draw (-2,-2) rectangle (2,2);
\end{tikzpicture}
\end{document}


• Please think carefully before down voting. Apr 12 '13 at 15:22
• @Jake: Please don't delete comments. Downvote cancelled but nothing changes. Apr 12 '13 at 15:30
• I have added a more TikZ-ish way to extend this approach to be a little bit more flexible. Feel free to revert, if this is not in the spirit of your answer. (One could also hack the () syntax of the circle and ellipse path operator but this syntax is considered “old” anyway.) Apr 12 '13 at 16:49
• Karl's students: that's a very understandable and clear explanation. Upvoted. Apr 12 '13 at 22:53

The key idea of all the proposed solutions rely on changing the unitswith x= and y=. This works well.

However in my code it is highly desirable to stick with xscale= and yscale=. Therefore I have set up a very simple macro :

\newcommand{\pnt}[3][black]{%
\begin{scope}[shift={#2}];
\fill[color=#1,shift only] (0,0) circle(#3);
\end{scope}}


which is used with :

\pnt[red]{(3,4)}{0.06}


to place a circular red point of 1.5pt radius at location (3,4).