Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm trying to draw two loosely dotted lines, one with slope 0 (i.e. a horizontal line), the other upward sloping. Is there a way to horizontally align the dots in these two lines?

Here's a MWE. Basically what I want is to have the n-th dot on each line be aligned in such a way that you could draw a vertical straight line that passes through them. This is my attempt to draw two functions whose domain is a discrete set.

\documentclass[english,12pt]{article}

\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  \draw[loosely dotted,very thick](0,2)--(5,2);
  \draw[loosely dotted,very thick](0,0)--(5,5);
  \draw[<->,>=latex](0,6)node[left]{$y$}--(0,0)--(6,0)node[below]{$x$};
\end{tikzpicture}

\end{document}
share|improve this question
5  
It would be helpful if you composed a fully compilable MWE including \documentclass and the appropriate packages that sets up the problem. While solving problems can be fun, setting them up is not. Then, those trying to help can simply cut and paste your MWE and get started on solving the problem. –  Peter Grill Feb 19 '13 at 6:06
    
Can you identify the problem with \draw[loosely dotted] (0,0) --++(2,0) --++(60:2); too? –  percusse Feb 19 '13 at 8:42

2 Answers 2

up vote 5 down vote accepted

Result

In this particular case, it can be done, as the above figure proves, but I guess that you aimed for a more general solution, which does not exist if the lines to draw are general curves.

For the case of straight lines, the trick is to define a "dotted parttern" with the appropiate separation among dots. In this particular case, I used 5pt of separation for the horizontal line (1pt "on", 4pt "off"). Since the diagonal line is at 45 degrees, the required separation has to be 5*sqrt(2), or in general 5*tan(angle). This lead to 1pt "on", 6.071 "off", so that the distance among dots is 7.071 (5*sqrt(2)).

The code which produced the above figure was:

\tikzset{
  horizontal dotted/.style = {
      dash pattern = on 1pt off 4pt,
      line width =0.8pt
  },
  diagonal dotted/.style = {
      dash pattern = on 1pt off 6.071pt,
      line width =0.8pt
  }
}

\begin{tikzpicture}[line cap=square]
  \draw[horizontal dotted](0,2)--(5,2);
  \draw[diagonal dotted](0,0)--(5,5);
  \draw[<->,>=latex](0,6)node[left]{$y$}--(0,0)--(6,0)node[below]{$x$};
  \foreach \x in {0,5,...,140} {
    \draw[very thin, help lines] (\x pt + 0.5pt, 0pt) -- +(0,5);
   }
\end{tikzpicture}

Note that, with some effort, this solution can be generalized for straight lines, so that the required distance among dots in the diagonal line can be computed from its starting and ending points. But since I don't know the actual use case for this, I don't know if the effort is worth.

Update

A different approach which could be more general. Very hackish!

Now the trick is to define a "fill pattern" which consists on vertical stripes (filled rectangles) of a given width (I used 1pt) and separated a given distance (I used 2mm). Then, draw the lines using that fill pattern. This should work because the pattern is somehow drawn "behind" the figure, and the filled regions are only "holes" which allow to see the pattern, so those stripes will be "in phase" for all filled regions which use that pattern.

The problem of course is that fill patterns cannot be applied to lines, only to closed shapes, so I had to invent another hack to convert the lines to be drawn in rectangles which can be filled this way. I thought that the easiest way is to use a sloped rectangular node which spawns between the extremes of the line.

This is the complete code. I allowed for specifying the color of the filling pattern, which translates to the color of the "dots":

\usetikzlibrary{calc,patterns}

\pgfdeclarepatternformonly{stripes}
{\pgforigin}{\pgfpoint{1cm}{2cm}}
{\pgfpoint{2mm}{1cm}}  % Change 2mm for the required distance among "dots"
{
\pgfpathmoveto{\pgfpoint{0}{0}}
\pgfpathlineto{\pgfpoint{1pt}{0}}    % Change 1pt for the desired width of the "dots"
\pgfpathlineto{\pgfpoint{1pt}{1cm}}
\pgfpathlineto{\pgfpoint{0}{1cm}}
\pgfpathclose%
\pgfusepath{fill}
}

\tikzset{
  trick/.style = {
    midway, draw=none, minimum height=.8pt,
    inner sep=0pt,sloped,
    pattern = stripes, pattern color= #1,
  },
  trick/.default = {black},
}

\newcommand{\linedraw}[3][black]{
\path let 
    \p1=($(#3)-(#2)$),
    \n1={veclen(\p1)}
 in (#2) -- (#3) node[trick=#1, minimum width=\n1] {};
}

\begin{tikzpicture}[line cap=square]
  \linedraw{0,2}{5,2};
  \linedraw{0,0}{5,5};
  \linedraw[red]{1,4}{4.5,0};
  \draw[<->,>=latex](0,6)node[left]{$y$}--(0,0)--(6,0)node[below]{$x$};
  \foreach \x in {1,3,...,50} {
    \draw[very thin, help lines] (\x mm + 0.5pt, 0) -- +(0,5);
  }
\end{tikzpicture}

And this is the result:

Result

share|improve this answer
    
Hmm I get the question wrong then. I tried to match the intersection dots coincide. –  percusse Mar 30 '13 at 13:24

Inspired by JLDiaz's use of foreach, I come up with the following try, which allows for plotting simple non-linear functions. I have to remove the point at 0 to avoid division by zero.

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
  \foreach \x in {5,10,...,140}{
    \draw[very thin, help lines] (\x pt, 0pt) -- +(0,5);
    \draw[fill=black]
      (\x pt,1)circle(.5pt) 
      (\x pt,\x pt)circle(.5pt) 
    ;
    \draw[red,fill=red](\x pt,25/\x)circle(.5pt);   % y=25/x
    \draw[blue,fill=blue](\x pt,\x^.3)circle(.5pt); % y=x^{0.3}
  }
  \draw[<->,>=latex](0,6)node[left]{$y$}--(0,0)--(6,0)node[below]{$x$};
\end{tikzpicture}

\end{document}

plot function on discrete domain

share|improve this answer
1  
Of course, this is the better approach, and one I thought too for the case of general curves (i.e. not straight lines). But in the end I succumbed to the hacking challenge of the original question :-) –  JLDiaz Mar 30 '13 at 18:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.