# Adding condition to \DTLplot (dataplot package)

I'm working with the package datatool for a while now, and I'd like to make graphs of my created databases. But I do not want to plot all rows in my database so I'd like to use the condition. This is an extract from the manual from the datatool-package:

\DTLplot[<condition>]{<db list>}{<settings>}


This command creates a plot (inside a tikzpicture environment) of all the data given in the databases listed in <db list>, which should be a comma separated list of database names. The optional argument <condition> is the same as that for \DTLforeach. The <settings> argument is a comma separated list of <setting>=<value> pairs. There are two settings that must be specified x and y. The other settings are optional.

In the next part I'm going to explain how datatool works for those who are unfamiliar with the package. If you already know how it works skip to the next title.

Introduction to datatool

I'll give an example for \DTLforeach. Create the file score.txt with contents:

FirstName,Surname,StudentNo,Score
John,Smith,102689,68
Jane,Brown,102647,75
Andy,Brown,103569,42
Clare,Verdon,104356,45


The code to load and print the database:

\documentclass{article}
\usepackage{datatool}
\DTLloaddb{score}{score.txt}  % create the database score

\begin{document}
\DTLdisplaydb{score}  % prints the database
\end{document}


The text in bold are called keys, headers or identifiers. Those can be used to assign data to a command. I'll explain with the command \DTLforeach:

The command \DTLforeach[<condition>]{<db name>}{<assign list>}{<text>} iterates through each row of the database and executes <text> when <condition> is met. E.g. when I want to count how many students have a score greater than 60 I could write this:

\documentclass{article}
\usepackage{datatool}

\begin{document}
\newcounter{nostudents}
\DTLforeach[\DTLisgt{\Score}{60}]{score}{\Score=Score}{\stepcounter{nostudents}}
A total of \arabic{nostudents}\ have a score higher than 60.
\end{document}


The assign list works like this: <cmd>=<key>, where for each row the value in the column Score is stored in \Score. The command \DTLisgt simply checks if arguments 2 is greater than argument 1.

My actual question

I'll use the same file as in the previous section and I now want to make a (useless) graph (in this case) of the students with score greater than 60 vs their Student Number. To make a graph of everyone is simple: \DTLplot{score}{x=StudentNo, y=Score} will do the job. But with conditions I need an <assign list> which is not available for \DTLplot it seems. So writing

\DTLplot[\DTLisgt{\Score}{60}]{score}{x=StudentNo, y=Score}


will result in an error because he does not know the command \Score. Adding \Score=Score to the last argument will result in the same error.

If you could just react if you know a solution or not that will be great. If I don't get any answer I'll contact the package maintainer. I don't like to disturb him too much with lousy questions :)

-

This seems to be a bug in the dataplot package. It calls

\@sDTLforeach[#1]{\dtl@thisdb}{\dtl@x=\dtl@xkey,%
\dtl@y=\dtl@ykey}{...


So it passes the condition along, but gives no opportunity to add a assign list. I don't think it is possible to add to this assignment list of the inner foreach from the outside. Notice that the settings argument is not even meant to provide such a thing.

What you could do in this special case, is use the miny setting:

\DTLplot{score}{x=StudentNo, y=Score, miny=60}


Of course this does not make arbitrary conditions possible and unfortunately it does not change the range of plotted x-values.

This plot type is probably not fitted for that kind of data and relation given in the example anyway. The databar package provides a way to create bar charts and allows the use of a condition. Here the code is

\DTLbarchart[\DTLisgt{\Score}{60}]{
barlabel=\StudentNo,
upperbarlabel=\Score,
variable=\Score}{score}
{\Score=Score,\StudentNo=StudentNo}


Patching \DTLplot with etoolbox is not possible because it takes an optional argument and I don't have xpatch to work around this. Also the following thing has to be changed:

\DTLcomputebounds[#1]{#2}{\dtl@xkey}{\dtl@ykey}
{\DTLminX}{\DTLminY}{\DTLmaxX}{\DTLmaxY}%


If you look at the documentation of \DTLcomputebounds there is not optional argument and also no way to pass an assign list. Still the implementation does contain the optional argument. In other words, this looks a little like a work in progress.

-
You still can patch \DTLplot: \expandafter\patchcmd\csname\string\DTLplot\endcsname{<before>}{<after>}{<succe‌​ss>}{<failure>}, which is what \xpatchcmd does behind the scenes. –  egreg Sep 21 '12 at 9:32