1

I'd like to produce a scatter plot using pgfplots with points belonging to different classes. The point colors should be determined through a class column in the data, which refers to an index in a colormap.

\documentclass[margin=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{tikzpicture}

\pgfplotsset{colormap={mymap}{
rgb=(0.8,0.0,0.0)
rgb=(0.0,0.8,0.0)
rgb=(0.0,0.0,0.8)
}}

    \begin{axis}
        \addplot [
            scatter,
            mark=*,
            only marks,
            point meta=\thisrowno{2},
            % colormap access=direct   % NB
        ] table {
            0 0 0
            1 1 1
            2 2 0
        };

    \end{axis}
\end{tikzpicture}

\end{document}

So far, the color mapping works as a linear map. That means:

  • The outer points are rendered red (lowest meta value => lowest color value)
  • The inner point is rendered blue (highest meta value => highest color value)

I'd like to use the colormap as a color palette, so that I can directly specify the used color, regardless of other points' meta value:

  • The outer points should be rendered red (meta value 0 => pick color 0 from colormap)
  • The inner point should be rendered green (meta value 1 => pick color 1 from colormap)

The documentation includes an example ("Lena" image), using colormap access=direct. It seems that it's exactly what is needed:

The choice "direct" does not perform any transformation; it interprets the value of point meta as integer indices into the current color map.

However, when activated, I get the following error:

Package PGF Math Error: Could not parse input '0.8,0.0,0.0' as a floating point number, sorry. The unreadable part was near ',0.0,0.0'..

There is a slew of further errors, including Runaway argument?, but I deem them subordinate to the root error.

The error does not occur if colormap access=direct is commented out. The problem occurs with pdflatex, lualatex on TeX Live 2019; I also ran this on Overleaf, which uses pdflatex on TeX Live 2020, resulting in the same error.


I can think of a workaround: split the data into separate classes myself, and use one \addplot per class, specifying the corresponding color individually. That seems cumbersome.

Do you know why the error comes up? Am I doing something wrong?

2 Answers 2

2

Don't ask me too much why, but after reading the pgfplots manual trying to find out why your example doesn't work, I discovered that colormap access=direct works fine here if one uses \addplot[point meta=explicit symbolic, ...] table[meta index=2] .... Using explicit instead of explicit symbolic brings back the same error as in your example. I find this is a bit strange, because in the matrix plot example from the manual that is used to illustrate colormap access=direct (see section Using Colormaps as Indexed Color Space (Palette) on p. 236 in Revision 1.17 (2020/02/29) of the manual), the point meta is treated numerically with point meta=explicit. It would appear that scatter doesn't handle point meta in the same way as matrix plot.

\documentclass[tikz,border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{tikzpicture}

\pgfplotsset{colormap={mymap}{
  rgb=(0.8,0.0,0.0)
  rgb=(0.0,0.8,0.0)
  rgb=(0.0,0.0,0.8)
}}

\begin{axis}
    \addplot [
        scatter,
        mark=*,
        only marks,
        point meta=explicit symbolic,
        colormap access=direct,
    ] table[meta index=2] {
        0 0 0
        1 1 1
        2 2 0
    };
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Note that it is not necessary to provide indices in the colormap definition with this solution: it does yield

0 0.8 0 rg

for the middle point in the PDF stream, without any need to use the following syntax from your answer:

rgb(0)=(0.8,0.0,0.0)
rgb(1)=(0.0,0.8,0.0)
rgb(2)=(0.0,0.0,0.8)

It is not necessary to provide point meta min or point meta max either. The palette appears to be used in a straightforward way.

0

Using point meta min and point meta max keys, we can spread the range of used color indices, giving us a mapping independent of what meta values actually occur in the data. That means that the middle point is in fact rendered green:

\documentclass[margin=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{tikzpicture}

\pgfplotsset{colormap={mymap}{
rgb=(0.8,0.0,0.0)
rgb=(0.0,0.8,0.0)
rgb=(0.0,0.0,0.8)
}}

    \begin{axis}
        \addplot [
            scatter,
            mark=*,
            only marks,
            point meta=\thisrowno{2},
            point meta min=0,
            point meta max=2, % the max color of the colormap
        ] table {
            0 0 0
            1 1 1
            2 2 0
        };

    \end{axis}
\end{tikzpicture}

\end{document}


We could leave it here, but inspecting the generated PDF shows a slightly wrong green for the middle point:

0.00004 0.79995 0 rg

Using colormap coordinates helps here:

\pgfplotsset{colormap={mymap}{
rgb(0)=(0.8,0.0,0.0)
rgb(1)=(0.0,0.8,0.0)
rgb(2)=(0.0,0.0,0.8)
}}

Giving us:

0 0.8 0 rg

Note that this last addition in itself (using colormap coordinates) is not a fix to the original problem, even if combined with colormap access=direct.

You must log in to answer this question.

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