3

It looks like when I try to scale coordinate data in a pgfplots, I cannot do it in log scale simply, since the expression filter seems to be applied to the final point and not the table value.

For example, I expect these two commands to produce basically the same plot:

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[ymode=log] % ymode=normal works well!
\addplot+[] table[
x expr=\thisrow{X}*1., y expr=\thisrow{Y}*3, row sep=\\
]{
X Y \\
1 1.1 \\
2 11 \\
3 110 \\
} node[]{};
\addplot+[x filter/.code={\pgfmathparse{\pgfmathresult*1.}\pgfmathresult}, 
y filter/.code={\pgfmathparse{\pgfmathresult*3.}\pgfmathresult}] 
plot coordinates
{
 ( 1, 1 )
 ( 2, 10)
 ( 3, 100)
};
\end{axis}
\end{tikzpicture}
\end{document}

However I get this,

wrongplot

where the red line (coordinates version) is not the expected result. For example the last red point is about 10^6 and not about 300.

(Using ymode=normal produces the expected graph)

Obviously y filter/.code is not doing what I expected. I remember reading something about this in the manual. Maybe it is by design.

The question is: Is there another way of applying this transformation so it works for linear and log plot (just changing the value of ymode)? Or I have to switch to the plot table-based code altogether?

alfC
  • 14,350
  • In logarithmic plots, \pgfmathresult is already the log of the coordinate in the filter. So it needs \pgfmathresult+log10(3)) instead of a multiplication. – percusse Jun 10 '14 at 06:36
  • @percusse, ok but can I apply/access the data point "earlier". – alfC Jun 10 '14 at 07:05
  • 1
    I think it would be best to switch to \addplot table based plots, since they're more powerful and in my opinion also more convenient. Do you have a particular reason for wanting to stick with \addplot coordinates? – Jake Jun 10 '14 at 07:23
  • @Jake, yes. It is mostly historical reason. I think I am going to use table exclusively from now on, since I always find coordinates to behave oddly with respect to transformations (I need the feature to convert units in plots). For example another "problem"/odd behavior I found is http://tex.stackexchange.com/questions/154084/how-to-scale-both-data-and-error-bars-in-pgfplots – alfC Jun 10 '14 at 07:30
  • The reason why it is not that easy is because coordinate input is accumulated directly, so you can use an inverse transformation but it won't be as easy as changing the ymode (you can build your own style of course but tedious nevertheless). I would also recommend switching to tables. Coordinate parsing is faster but as you noticed limited in functionality. – percusse Jun 10 '14 at 08:07

1 Answers1

2

This is a possible solution. For ymode=log the default is for natural log, basis e, not for base 10. To work for log10, the axis option log basis y=10 is required

\begin{axis}[ymode=log,log basis y=10] ... \end{axis}

Also log (ab/cd) =log a+ log b -log c- log d so the OP's filter code is incorrect

y filter/.code={\pgfmathparse{\pgfmathresult*3.}\pgfmathresult}

The demonstration is for natural log, ln; For log10, one needs to add the aforementioned skill accordingly and \pgfmathresult+log10(3) in the filter code.

enter image description here

Code

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[ymode=log] % ymode=normal works well!
\addplot+[] table[
x expr=\thisrow{X}*1., y expr=\thisrow{Y}*3, row sep=\\
]{
X Y \\
1 1.1 \\
2 11 \\
3 110\\
} node[]{};
\addplot+[%x filter/.code= {\pgfmathparse{\pgfmathresult*1.}\pgfmathresult}, 
y filter/.code= {\pgfmathparse{\pgfmathresult+ln(3)}\pgfmathresult}
] 
plot coordinates
{
 ( 1, 1)
 ( 2, 10)
 ( 3, 100)
};
\end{axis}
\end{tikzpicture}
\end{document}
Jesse
  • 29,686
  • thanks for the workaround. From an interface point of view it would be good to have a way to do it that allow to purely change y mode without worrying to change the parsing. – alfC Jun 10 '14 at 18:28