The following code solves the plotting problem for tables like the one in your example. The solution applies \addplot
twice for each point: once for the fill and another time for the draw colour.
\documentclass[10pt,a4paper,landscape]{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\pgfplotstableread[row sep = \\]{
X Y C1 C2 Mark \\
1 1 0 6 * \\
2 2 6 0 otimes* \\
3 1 0 0 square* \\
4 5 6 6 diamond* \\
}\thetable
\pgfplotstablegetrowsof{\thetable}
\pgfmathsetmacro{\rowsminus}{\pgfplotsretval-1}
\foreach \i in {0,...,\rowsminus} {
\pgfplotstablegetelem{\i}{X}\of\thetable
\pgfmathsetmacro{\x}{\pgfplotsretval}
\pgfplotstablegetelem{\i}{Y}\of\thetable
\pgfmathsetmacro{\y}{\pgfplotsretval}
\pgfplotstablegetelem{\i}{C1}\of\thetable
\pgfmathsetmacro{\fillcolor}{\pgfplotsretval}
\pgfplotstablegetelem{\i}{C2}\of\thetable
\pgfmathsetmacro{\drawcolor}{\pgfplotsretval}
\pgfplotstablegetelem{\i}{Mark}\of\thetable
\edef\mymarkshape{\pgfplotsretval}
\addplot[
scatter,
point meta = \fillcolor,
visualization depends on = {value \mymarkshape \as \markshape},
scatter/use mapped color = {color=mapped color, draw opacity=0},
scatter/@pre marker code/.append style = {/tikz/mark = \markshape},
] coordinates {
(\x,\y)
};
\addplot[
scatter,
point meta = \drawcolor,
visualization depends on = {value \mymarkshape \as \markshape},
scatter/use mapped color = {color=mapped color, fill opacity=0},
scatter/@pre marker code/.append style = {/tikz/mark = \markshape},
] coordinates {
(\x,\y)
};
}
\end{axis}
\end{tikzpicture}
\end{document}
The following example code might help you solve the other part of the question, if I understood what you are after.
The code accepts metadata in another format: a string consisting of comma-separated "visualization classes" in column Meta
. Each class only affects one aspect of style (fill color, drawing color, or plot mark), but it would be easy to define more complex classes. If the style of some point should be left at the default settings, an unknown class name such as default
can be used as the Meta
value of the point.
I used the following sources of information:
\documentclass[10pt,a4paper,landscape]{article}
\usepackage{pgfplots}
\usepackage{etoolbox}
\usepackage{xstring}
\begin{document}
% Handler for metadata, ignores unknown strings
\newcommand{\mymetahandler}[1]{%
\IfStrEqCase{#1}{%
{A}{\pgfmathsetmacro{\fillcolor}{0}}%
{B}{\pgfmathsetmacro{\fillcolor}{6}}%
{a}{\pgfmathsetmacro{\drawcolor}{0}}%
{b}{\pgfmathsetmacro{\drawcolor}{6}}%
{aa}{\edef\mymarkshape{*}}%
{bb}{\edef\mymarkshape{otimes*}}%
{cc}{\edef\mymarkshape{square*}}%
{dd}{\edef\mymarkshape{diamond*}}%
}
}
\begin{tikzpicture}
\begin{axis}
\pgfplotstableread[row sep = \\]{
X Y Meta \\
1 1 A,b,aa \\
2 2 B,a,bb \\
3 1 A,a,cc \\
4 5 B,b,dd \\
}\thetable
\pgfplotstablegetrowsof{\thetable}
\pgfmathsetmacro{\rowsminus}{\pgfplotsretval-1}
\foreach \i in {0,...,\rowsminus} {
\pgfplotstablegetelem{\i}{X}\of\thetable
\pgfmathsetmacro{\x}{\pgfplotsretval}
\pgfplotstablegetelem{\i}{Y}\of\thetable
\pgfmathsetmacro{\y}{\pgfplotsretval}
% Default point style
\pgfmathsetmacro{\fillcolor}{0}
\pgfmathsetmacro{\drawcolor}{0}
\edef\mymarkshape{*}
% Call the handler for each comma-separated metadata item
\pgfplotstablegetelem{\i}{Meta}\of\thetable
\expandafter\forcsvlist\expandafter\mymetahandler\expandafter{\pgfplotsretval}
\addplot[
scatter,
point meta = \fillcolor,
visualization depends on = {value \mymarkshape \as \markshape},
scatter/use mapped color = {color=mapped color, draw opacity=0},
scatter/@pre marker code/.append style = {/tikz/mark = \markshape},
] coordinates {
(\x,\y)
};
\addplot[
scatter,
point meta = \drawcolor,
visualization depends on = {value \mymarkshape \as \markshape},
scatter/use mapped color = {color=mapped color, fill opacity=0},
scatter/@pre marker code/.append style = {/tikz/mark = \markshape},
] coordinates {
(\x,\y)
};
}
\end{axis}
\end{tikzpicture}
\end{document}
Best Answer
If I understood you correctly, you want to have fields in your PDF document displaying the current author as stated in the file's metadata. Like this, you want to be able to update the document by changing the metadata with an external program, which is easier than manipulating the text directly.
Theoretically, this is possible using PDF forms and Acrobat JavaScript: The
hyperref
package is capable of creating fillable forms, and with theinsdljs
package, you are able to insert the code to update a field with the document information. (insdljs
is part of the AcroTeX bundle, which is in MiKTeX, but not in TeX Live, so you may have to install it manually.)A proof of concept:
(
pdfauthor
is set so that the form field displays something, you can change the PDF author with an external program to see that it works.)Result:
However, this approach has two drawbacks:
Drawback #1 can be tackled by using the various formatting options described in the
hyperref
manual.To overcome drawback #2, I would suggest a different approach than using the document's metadata to update the text:
Create a PDF document containing a fillable form (this is pretty much the same we already did, but without the JavaScript part):
Create a so-called FDF (Forms Data Format) file containing the information you want to insert into the PDF document. For our minimal example, the file would look like this (replace
Firstname Lastname
with the name you want to insert):To create a "template" FDF file you can fill yourself, you can use the PDF toolkit
pdftk
:Now, you can write the prepared FDF file
form.fdf
into the original PDF formform.pdf
usingpdftk
:This may seem more work than the first approach, but as a result, you get a static document that can be viewed by any PDF reader.