9

For visualising the domain of definition of a function I want to create the following figure. enter image description here

I use the following code.

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}

\draw[help lines, color=gray!30, dashed] (-4.9,-4.9) grid (4.9,4.9);
\draw[->,ultra thick] (-5,0)--(5,0) node[right]{$x$};
\draw[->,ultra thick] (0,-5)--(0,5) node[above]{$y$};

\draw [thick] circle [radius=2];
\draw [thick] circle [radius=4];

\draw[double = gray!40, double distance=2cm, opacity=0.2] (0,0) circle (3);

\draw[->|, rotate around={30:(0,0)}] (0,0) -- (2,0)  node [midway,fill=white] {$2$};
\draw[->|, rotate around={60:(0,0)}] (0,0) -- (4,0)  node [midway,fill=white] {$4$};
\draw[fill=black](0,0) circle (2 pt) node [anchor=south east] {$O$};

\end{tikzpicture}
\end{document}

I get the following figure where I have added what I want to modify. enter image description here

Thank you very much for your help.

3
  • 1
    Removing fill=white in the node option; adding pos=.75 in the node option
    – Black Mild
    Dec 3, 2022 at 18:17
  • Why don’t you create the diagram with the drawing program you used to make the red text and arrows?
    – bubba
    Dec 5, 2022 at 12:54
  • @bubba It is just a basic screenshot program. I prefer tikz:-)!
    – Dimitris
    Dec 5, 2022 at 13:00

5 Answers 5

9

You could remove fill=white from the nodes and add near end (pos=.75) to the 4 node as such:

\draw[->|, rotate around={30:(0,0)}] (0,0) -- (2,0)  node [midway] {$2$};
\draw[->|, rotate around={60:(0,0)}] (0,0) -- (4,0)  node [near end] {$4$};

but this will give you
enter image description here
which doesn't look nice, does it?

Unfortunately, the mark connection node decoration doesn't like arrow tips but for straight paths, you just place the node first and then connect it with lines:

\path (0,0) -- node[near end] (4) {$4$} (60:4);
\draw[->|] (0,0) -- (4) -- (60:4);

Since this involves using each coordinate/name at least twice, I'll suggest putting this into a to path.

This needs some extra work because it uses an edge (which is also a to):

  • line to to get the original --(\tikztotarget)\tikztonodes to path (and not the one we are just defining),
  • path only to force no drawing, no filling, …,
  • all nodes along the path are aliased @nodeonline@ so we can use them later (the coordinate is a fallback in case no node has been used with the to path) and
  • sneaking in the \tikztonodes from the parent to but the internal version.

The latter uses \unexpanded in case there are any fragile macros part of the nodes (not your case).


A previous version of this answer provided a different solution that was more complicated than it needed to be (but didn't use any TikZ internals as this one does).

I prefer this one because it is as close to normal TikZ usage and can be used repeatedly on a path without the path being interrupted:

\tikz[inner sep=.15em, circle, nodes=draw, sloped]
  \draw[ultra thick, ->, node on line] (0,0) to["0"] (1,1)
                                             to["1"] (2,0)
                                             to["2"] (4,1);

enter image description here


If this is needed for more than one node, a bit more work is necessary.

Code

\documentclass[border=5mm, tikz]{standalone}
\usetikzlibrary{arrows.meta, quotes}% quotes for "syntax" on edges/tos
\makeatletter
\tikzset{
  node on line/.style={
    to path={
      \pgfextra{%
        \edef\tikz@temp{% rescuing nodes and target for edge
          edge[
            line to, path only, % line to = --, path only = no draw, no fill, …
            every edge quotes/.append style={auto=false},% node *on* the line
            nodes={alias=@nodeonline@}]
          coordinate(@nodeonline@)% fallback coordinate
          \unexpanded\expandafter{\tikz@tonodes}(\tikztotarget)
        }\expandafter
      }\tikz@temp
      -- (@nodeonline@) -- (\tikztotarget)}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[help lines, color=gray!30, dashed] (-4.9, -4.9) grid (4.9, 4.9);
\draw[->,ultra thick] (-5, 0) -- (5, 0) node[right]{$x$};
\draw[->,ultra thick] ( 0,-5) -- (0, 5) node[above]{$y$};

\draw [thick] circle [radius=2]
              circle [radius=4];

\draw[double = gray!40, double distance=2cm, opacity=0.2] (0,0) circle [radius=3];

% Short: polar coordinate and "syntax"
\draw[->|] (0,0) to[node on line, "$2$"] (30:2);
% Long:  rotate around and literal node after to
\draw[->|, rotate around={60:(0,0)}] % long form (short: "$4$" near end)
  (0,0) to[node on line] node[near end]{$4$} (4,0);

\draw[fill=black](0,0) circle [radius=2pt]
                       node [anchor=south east] {$O$};
\end{tikzpicture}
\end{document}

Output

enter image description here

6
  • +1! Where is defined \NewDocumentCommand option r? Your example works also if in definition of \nodeOnArrow command instead of r I use d.
    – Zarko
    Dec 3, 2022 at 21:10
  • @Zarko Page 2 of the manual. The r stands for required (which it is) while d is optional (delimited). Though, even r/R act like an optional argument, providing a default value when it is missing but raising an error at the same time. Since both coordinates are needed, I chose r. (Sure we could default the first to 0, 0 but that makes it ambiguous if it'll work at all.) I usually try to avoid defining document commands for things that only work inside a TikZ picture but its usage as a to path is limited – at least in its current form. Dec 3, 2022 at 22:10
  • Thank you very much for info and explanation. In first I didn't remember where is \NewDocumentCommand defined. BTW, for see my answer. In comparison with your astonishing solution is mine quite primitive, but works ;-)
    – Zarko
    Dec 3, 2022 at 22:36
  • Yeah, it's hard to find documentation on the base LaTeX stuff. Your answer is using the same concept as mine (place a node and use it as the connection for two line segments) but you need to repeat coordinates (even if they're named) what I want to avoid. Dec 3, 2022 at 22:47
  • 1
    huh, new solution is very demanding! I will need some time to figured out how it works.
    – Zarko
    Dec 4, 2022 at 8:06
8

A solution with similar concept as in a @Qrrbrbirlbel answer but without advanced new command and TikT style definition:

  • for vectors are used polar coordinates
  • vectors are drawn in two steps:
    • first is determined position of vector label
    • after then is drawn vector
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\begin{document}
    \begin{tikzpicture}[> = {Straight Barb[scale=1.2]}
                        ]
% circles
\draw[draw, double = gray!20, double distance=2cm] (0,0) circle [radius=3];
% axes
\draw[help lines, color=gray, dashed] (-4.9,-4.9) grid (4.9,4.9);
%
\draw[->,thick] (-5,0)--(5,0) node[right]{$x$};
\draw[->,thick] (0,-5)--(0,5) node[above]{$y$};
% vectors
    \path (0,0) coordinate (o) 
                to node (lbl) {$2$} ++ (30:2);
\draw[->] (o) -- (lbl) -- (30:2);
    \path (o) to node[pos=0.75] (lbl) {$4$} ++(60:4);
\draw[->] (o) -- (lbl) -- (60:4);

\fill   (0,0) circle [radius=2pt] node [above left] {$O$};
\end{tikzpicture}
\end{document}

enter image description here

Addendum:
A small variation od , for exercise:

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\NewDocumentCommand{\nodeOnArrow}{O{} % arrow option; but not used in MWE
                                  r() % as requires, anchor of arrows label node
                                  r() % as requires, anchor for end arrow
                                  O{} % node options (position on arrow, etc)
                                  m}  % content of node
{
                                     \path[style={#1}] (#2) edge[path only]
                       node[append after command={
                            (#2)            edge (\tikzlastnode)
                            (\tikzlastnode) edge[-{Straight Barb[scale=1.2]}] (#3)
                                                  }, style={#4}] {$#5$} (#3);
} % end of command

\begin{document}
    \begin{tikzpicture}
\draw[draw, double = gray!20, double distance=2cm] (0,0) circle [radius=3];

\draw[->,thick] (-5,0)--(5,0) node[right]{$x$};
\draw[->,thick] (0,-5)--(0,5) node[above]{$y$};

\nodeOnArrow    (0,0) (20:2) {2}
\nodeOnArrow    (0,0) (60:4) [pos=0.75] {4}    % or "near end"

\draw[fill=black](0,0) circle [radius=2pt] node [above left] {$O$};
    \end{tikzpicture}
\end{document}

Result is the same as at the first example.

6

Remove fill=white from your nodes. But then the line will pass through the text, so use above or above left to place them off the line. You can set values, e.g., above=-1pt to move the labels closer or farther away from the line. Finally, pos= will set the position (as a percentage of the total length) of the node. For example, midway is the same as pos=.5.

Also, you should use circle[radius=2pt] instead of circle (2 pt), which is deprecated (but still works for now).

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}

\draw[help lines, color=gray!30, dashed] (-4.9,-4.9) grid (4.9,4.9);
\draw[->,ultra thick] (-5,0)--(5,0) node[right]{$x$};
\draw[->,ultra thick] (0,-5)--(0,5) node[above]{$y$};

\draw [thick] circle [radius=2];
\draw [thick] circle [radius=4];

\draw[double = gray!40, double distance=2cm, opacity=0.2] (0,0) circle (3);

\draw[->|, rotate around={30:(0,0)}] (0,0) -- (2,0)  node [above=-1pt, midway] {$2$};
\draw[->|, rotate around={60:(0,0)}] (0,0) -- (4,0)  node [above left=-3pt, pos=.75] {$4$};
\draw[fill=black](0,0) circle[radius=2pt] node [above left] {$O$};

\end{tikzpicture}
\end{document}
5

Another method, admittedly not what exactly asked for, but still valid in my opinion, would be to use sloped to place the node tangent to the current slope of the path (in the case of a segment, the node will be parallel to the segment). Here is the code:

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}

\draw[help lines, color=gray!30, dashed] (-4.9,-4.9) grid (4.9,4.9);
\draw[->,ultra thick] (-5,0)--(5,0) node[right]{$x$};
\draw[->,ultra thick] (0,-5)--(0,5) node[above]{$y$};

\draw [thick] circle [radius=2];
\draw [thick] circle [radius=4];

\draw[double = gray!40, double distance=2cm, opacity=0.2] (0,0) circle (3);

\draw[->|] (0,0) -- (30:2)  node [midway, sloped, above] {$2$};
\draw[->|] (0,0) -- (60:4)  node [near end, sloped, above] {$4$};
\draw[fill=black](0,0) circle (2 pt) node [anchor=south east] {$O$};

\end{tikzpicture}
\end{document}

enter image description here

Note: I had to remove the parameter rotate around= and use instead polar coordinates, otherwise sloped did not work (not sure what's going on here).

Just for fun, here is an "improved" version with squiggly lines, as per the original picture:

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,decorations,decorations.pathmorphing}
\begin{document}
\begin{tikzpicture}[squigglyline/.style={decorate,decoration={random steps,segment length=1pt,amplitude=0.2pt}}]

\draw[help lines, color=gray!30, dashed, squigglyline] (-4.9,-4.9) grid (4.9,4.9);
\draw[->,ultra thick,squigglyline] (-5,0)--(5,0) node[right]{$x$};
\draw[->,ultra thick,squigglyline] (0,-5)--(0,5) node[above]{$y$};

\draw [thick,squigglyline] circle [radius=2];
\draw [thick,squigglyline] circle [radius=4];

\draw[double = gray!40, double distance=2cm, opacity=0.2,squigglyline] (0,0) circle (3);

\draw[->|,squigglyline] (0,0) -- (30:2)  node [midway, sloped, above] {$2$};
\draw[->|,squigglyline] (0,0) -- (60:4)  node [near end, sloped, above] {$4$};
\draw[fill=black](0,0) circle (2 pt) node [anchor=south east] {$O$};

\end{tikzpicture}
\end{document}

enter image description here

1
  • 1
    Interesting! The coordinates that TikZ gives to the PGF macro that does the rotation are the untransformed one, i.e. (2, 0) (or rather \pgfqpoint {56.90549pt}{0.0pt}) and the angle from (0, 0) to (2, 0) is obviously 0°. \draw[rotate around={20:(0,0)}](0,0)--(30:4)node[sloped]{$4$}; is giving a half rotated 4. Dec 4, 2022 at 0:10
2

Here is my suggestion.

enter image description here

% https://www.overleaf.com/read/khkhbwgqmjvt
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta} % for Barb arrow
\usepackage{asymptote}
\begin{document}
\begin{tikzpicture}[>={Straight Barb[angle=60:5pt]}]
\fill[yellow!50,even odd rule,draw=black] circle(2) circle(4);
\draw[gray!50,dashed] (-4.5,-4.5) grid (4.5,4.5);
\draw 
(-5,0)--(5,0) node[below]{$x$}
(0,-5)--(0,5) node[left]{$y$};
\draw[->,red] (0,0)--(30:2) node[pos=.8,below]{$2$};
\draw[->,blue] (0,0)--(60:4) node[pos=.7,below right] {$4$};
\draw[fill=white] circle(1.5pt) node[below left]{$O$};
\end{tikzpicture}
\hspace{1cm}
\begin{asy}
// http://asymptote.ualberta.ca/
size(10cm);
unitsize(1cm);
import graph;
import math;  // for grid
real r=2,R=4;
pair O=(0,0);
path p=circle(O,r),q=circle(O,R);
add(shift(-4,-4)*grid(8,8,gray+.2pt+dashed));
filldraw(p^^q,evenodd+green+opacity(.2));
draw(Label("$2$",Relative(.7),align=S),O--r*dir(30),red,Arrow(TeXHead));
draw(Label("$4$",Relative(.8),align=SE),O--R*dir(60),blue,Arrow(TeXHead));
dot("$O$",align=SW,O,FillDraw(white,black));
xaxis("$x$",-R-.5,R+.5);
yaxis("$y$",-R-.5,R+.5);
\end{asy}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .