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?

1

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.

| improve this answer | |
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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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