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.

Is it possible to make PGFPlots display 45° height lines in an axis? Basically, what I am looking for is a grid defined by y=-x + k*1000, k being a natural number. My numbers are rather large, e.g. y is between 54,000 and 59,000 and x between 0 and 5000 for one of my plots, which causes dimension too large errors when employing Jake's solution. Is there a way to achieve this without plotting the grid lines as functions? The respective plot is axis equal.

share|improve this question
    
Do you want the grid lines to cover the whole plot area (which they won't necessarily do if k only runs from ymin to ymax)? And are all limits (xmin, xmax, ymin, ymax) manually set? –  Jake May 14 '11 at 14:39
    
Yes, they should cover the whole plot area. The plots are square, some have axis equal=true set, others (for which axis equal=true did not work) have all limits set manually to ensure the same unit length for x and y. To give you an idea what I am trying to do here: The lines represent bands in which the sum of x and y is the same. –  Jannik Jochem May 14 '11 at 14:57

1 Answer 1

up vote 4 down vote accepted

Update: Now works with large numbers

Here's a macro (and accompanying pgfplots style) which draws a diagonal grid with a gradient of -1. It works regardless of the unit lengths of the plot and regardless of whether the axis limits are set explicitly or not. It will work with large numbers, but care must be taken to select an adequate diagonal grid spacing, as the \foreach loop cannot handle more than 45000 entries (then again, that many grid lines probably wouldn't make much sense).

What it does first is to determine the width and height of the plot in plot dimensions by querying the key /pgfplots/xmin, /pgfplots/xmax etc. This has to happen after all the plots have been defined, as otherwise the values could still change. That's why the macro uses \pgfplotsextra{}, which tells pgfplots to execute the code at the end of the so called "surveying phase', i.e. after everything has been defined, but before it has actually been drawn.

After the number of required grid lines have been determined from the width and height of the plot, a \foreach loop is executed which draws the lines. It uses the every axis grid style, so that you can influence the appearance of the diagonal grid lines in the same way as you would with normal grid lines.

To activate the diagonal grid in an axis, just use the key diagonal grid in the axis options.

Here's an example of the output:

pgfplots plot with diagonal grid lines

And here's the implementation. The option execute at begin plot is only available in the development version of PGFPlots. For earlier versions, just call \diagonalgrid before the first plot. The spacing of the lines can be adjusted using the key diagonal grid spacing:

\documentclass{article}

\usepackage{pgfplots}

\newcommand{\diagonalgrid}{
    \pgfplotsextra{
        \pgfkeys{/pgf/fpu}
        \pgfmathparse{\pgfkeysvalueof{/pgfplots/diagonal grid spacing}}
        \let\spacing=\pgfmathresult
        \pgfmathparse{\pgfkeysvalueof{/pgfplots/xmin}}
        \let\xmin=\pgfmathresult
        \pgfmathparse{\pgfkeysvalueof{/pgfplots/xmax}}
        \let\xmax=\pgfmathresult
        \pgfmathparse{\pgfkeysvalueof{/pgfplots/ymin}}
        \let\ymin=\pgfmathresult
        \pgfmathparse{\pgfkeysvalueof{/pgfplots/ymax}}
        \let\ymax=\pgfmathresult
        \pgfmathparse{round((\pgfkeysvalueof{/pgfplots/xmin}-\spacing)/\spacing)*\spacing}
        \let\roundxmin=\pgfmathresult
        \pgfmathfloattofixed{\pgfmathresult}
        \let\fixedxmin=\pgfmathresult\fixedxmin
        \pgfmathparse{round((\pgfkeysvalueof{/pgfplots/xmax}+\spacing)/\spacing)*\spacing}
        \let\roundxmax=\pgfmathresult
        \pgfmathparse{round((\pgfkeysvalueof{/pgfplots/ymin}-\spacing)/\spacing)*\spacing}
        \let\roundymin=\pgfmathresult
        \pgfmathfloattofixed{\pgfmathresult}
        \let\fixedymin=\pgfmathresult
        \pgfmathparse{round((\pgfkeysvalueof{/pgfplots/ymax}+\spacing)/\spacing)*\spacing}
        \let\roundymax=\pgfmathresult
        \pgfmathparse{(\roundxmax-\roundxmin + \roundymax-\roundymin)/\spacing}
        \pgfmathfloattofixed{\pgfmathresult}
        \let\totalnumber=\pgfmathresult
        \foreach \n in {0,...,\totalnumber}{
            \pgfmathparse{(\n * \spacing+ \roundxmin)}
            \pgfmathfloattofixed{\pgfmathresult}
            \let\currentxmin=\pgfmathresult
            \pgfmathparse{(\n * \spacing+ \roundymin)}
            \pgfmathfloattofixed{\pgfmathresult}
            \let\currentymin=\pgfmathresult
            \pgfkeys{/pgf/fpu=false}
            \draw [/pgfplots/every axis grid] (axis cs:\fixedxmin,\currentymin) -- (axis cs:\currentxmin,\fixedymin);
        }
    }
}
\pgfkeys{/pgfplots/diagonal grid/.style={execute at begin axis={\diagonalgrid}}}
\pgfkeys{/pgfplots/diagonal grid spacing/.initial={1}}

\begin{document}

\begin{tikzpicture}
\begin{axis}[axis equal,grid=both,diagonal grid,diagonal grid spacing=1000]
\addplot [domain={10000:15000}]{-0.2*x+50000};
\end{axis}
\end{tikzpicture}


\end{document}
share|improve this answer
    
@Jake - First of all: Thank you very much for your help! However, the above code fails to compile for me with the error message ! Package pgfkeys Error: I do not know the key '/tikz/execute at begin axis'.... I have PGFPlots 1.4.1 installed. Is this based on a development snapshot? –  Jannik Jochem May 15 '11 at 12:46
    
@Jannik: Oh yes, sorry for that. I didn't know the key was introduced so recently. I've updated my answer to include an approach that should work with the stable release. It requires the backgrounds TikZ library to be able to get the grid lines behind the plots. –  Jake May 15 '11 at 13:01
    
@Jake the background clipping does not seem to work correctly. Compiling your example yields a plot that has diagonal lines drawn only over a small part. I switched to pgfplots git instead. Your example works nicely. However, the plots I draw have very large dimensions. Using diagonal grid results in a dimension too large error. I want to draw diagonal grid lines only every 1000 units. How would I modify the code for this? –  Jannik Jochem May 15 '11 at 13:23
    
@Jake: Wow, amazing. However, I still get "Dimension too large" errors when I apply your solution to my data. One plot for which it fails is set to ymin=49000,ymax=54000,xmin=0,xmax=5000. Setting domain={49000:54000} in your example reproduces the problem. Is there any way to work around that? –  Jannik Jochem May 15 '11 at 14:01
1  
Nice work Jake! Thank you very much! –  Jannik Jochem May 17 '11 at 9:10

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.