# pgfplots: how to load distinct symbolic ticks/labels from file?

I want to plot a matrix of color-values from a csv file. Inspired by this website, I set out to write my MWE below, to which I added this way of dynamically loading symbolic ticks/labels from my data file.

However, It turns out that my resulting ticks/labels are not distinct, but instead are repeated, like my rendering shows.
Another way to think of it (according to @Jake's comments) is that flexible (x|y)ticklabels from table does not tell PGFplots that these labels are supposed to be symbolic, as doing it manually using symbolic (x|y) coords would.

How can I tell PGFplots that all distinct values from the xitem and yitem columns in my data file are to be used as symbolic labels?
Maybe the problem lies within (x|y) expr=\coordindex. What I want here is to fill in the (symbolic, not numerical) value from the respective colum (xitem|yitem). But using x=xitem,y=yitem, instead gives the error "Package PGF Math Error: Could not parse input 'X' as a floating point number".

Rendering:

MWE:

\documentclass{standalone}

\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}

\begin{filecontents}{data.csv}
yitem,xitem,val
r,X,0.1
r,Y,0.2
r,Z,0.3
d,X,0.4
d,Y,0.5
d,Z,0.6
j,X,0.5
j,Y,0.8
j,Z,0.9
\end{filecontents}

\makeatletter
\pgfplotsset{
/pgfplots/flexible xticklabels from table/.code n args={3}{
\pgfplotstablegetcolumn{#2}\of{\coordinate@table}\to\pgfplots@xticklabels
\let\pgfplots@xticklabel=\pgfplots@user@ticklabel@list@x
},
/pgfplots/flexible yticklabels from table/.code n args={3}{
\pgfplotstablegetcolumn{#2}\of{\coordinate@table}\to\pgfplots@yticklabels
\let\pgfplots@yticklabel=\pgfplots@user@ticklabel@list@y
}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{axis}[
flexible xticklabels from table={data.csv}{xitem}{col sep=comma},
xtick=data,
flexible yticklabels from table={data.csv}{yitem}{col sep=comma},
ytick=data,
unbounded coords=jump,
]
mark=square*,
only marks,
scatter,
point meta=explicit,
] table [
col sep=comma,
x expr=\coordindex,
y expr=\coordindex,
meta expr=\thisrow{val},
] {\datatable};

\end{axis}
\end{tikzpicture}
\end{document}

• With the table you currently use, you'll need to use symbolic x coords={a,b,c} and symbolic y coords={X,Y,Z} (while also removing x expr=\coordindex, y expr=\coordindex). That's a bit cumbersome to work with, though. There might be better ways to organise your data. How do you generate your data table? – Jake Jan 13 '14 at 15:26
• The table I posed here is just an example; My actual use case contains 25000 rows and 30 columns. I wish there was a way to adapt flexible (x|y)ticklabels from table in a way that it filters duplicates. But I don't know how. – derabbink Jan 13 '14 at 15:35
• flexible ticklabels from table won't help here, because that's just for generating the labels, but not the coordinates. You're currently plotting the data points at (i|i), where i is the coordinate index, so filtering duplicates out of the labels won't help you. Rather, you need to map a, b, c... to x=1, 2, 3... and X, Y, Z to y=1, 2, 3... (which is what symbolic x coords does). – Jake Jan 13 '14 at 15:38
• If you could create a table that contains proper numerical coordinates instead of the symbolic ones, things would be much easier. – Jake Jan 13 '14 at 15:39
• I can generate numbers/IDs representing a,b,c and X,Y,Z, but eventually I need these original values (not the IDs) to be written near the axes. – derabbink Jan 13 '14 at 15:42

You need to generate the mapping from the symbolic coordinates to Cartesian coordinates. If the Cartesian coordinates correspond to the rank of the first appearance of a symbol in a column, you can use the etoolbox package to generate a list that represents the mapping, and then use symbolic x coords to pass that mapping to PGFPlots:

\documentclass[border=5mm]{article}

\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepackage{etoolbox}

\begin{filecontents}{data.csv}
yitem,xitem,val
a,X,0.1
a,Y,0.2
a,Z,0.3
b,X,0.4
b,Y,0.5
b,Z,0.6
c,X,0.5
c,Y,0.8
c,Z,0.9
\end{filecontents}

\begin{document}
\def\xlistmacro{}
\def\xliststring{}
\pgfplotstableforeachcolumnelement{xitem}\of\datatable\as\entry{%
\xifinlist{\entry}{\xlistmacro}{}{
\edef\xliststring{\xliststring\entry,}
}
}

\def\ylistmacro{}
\def\yliststring{}
\pgfplotstableforeachcolumnelement{yitem}\of\datatable\as\entry{%
\xifinlist{\entry}{\ylistmacro}{}{
\edef\yliststring{\yliststring\entry,}
}
}

\begin{tikzpicture}
\begin{axis}[
xtick=data,
ytick=data,
symbolic x coords/.expand once={\xliststring},
symbolic y coords/.expand once={\yliststring},
]
mark=square*,
only marks,
scatter,
point meta=explicit,
] table [
col sep=comma,
meta expr=\thisrow{val},
x=xitem, y=yitem
] {\datatable};

\end{axis}
\end{tikzpicture}
\end{document}