% Copyright 2013 Thomas Koenig, Alexander Michel, Michael Baumgart
%
% This file is part of NumericPlots.
%
% NumericPlots is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% any later version.
%
% NumericPlots is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with NumericPlots. If not, see .
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{NumericPlots}%
[2013/09/19 v. 2.0.2 LaTeX package to plot numeric data]
\RequirePackage{calc}
\RequirePackage[nomessages]{fp}
\RequirePackage{ifthen}
\RequirePackage{pstricks}
\RequirePackage{pst-node}
\RequirePackage{pst-plot}
\RequirePackage{pstricks-add} % has to be the last of the pst-packages to be loaded!
% the following seems not to work. xcolor must be included with x11names option!
\RequirePackage{xcolor}
% \makeatletter
% \newcommand*{\getlengthwounit}[1]{\strip@pt#1}
% \makeatother
% =======================================
% === Definition of keys and commands ===
% =======================================
%
% All the provided options (keys) are defined in the following section. Maybe it
% is possible to store the values of the keys somehow. We then wouldn't have to
% define all the new commands..
\RequirePackage{xkeyval}
\RequirePackage{xkvview} % keep track of all keys that are defined
\newcommand{\testframe}[1]{#1}
% globally needed values as newcommands
\newcommand{\NumDataPlotxRange}{1}
\newcommand{\NumDataPlotxCoordRange}{1}
\newcommand{\NumDataPlotxDataCoordRatio}{1}
\newcommand{\NumDataPlotyRange}{1}
\newcommand{\NumDataPlotyCoordRange}{1}
\newcommand{\NumDataPlotyDataCoordRatio}{1}
\newcommand{\NumDataPlotLnTen}{2.3025850929940}
\newcommand{\NumDataPlotTickPos}{0}
\newcommand{\xScaling}{}
\newcommand{\yScaling}{}
\newcommand{\NDPputXcoord}{0}
\newcommand{\NDPputYcoord}{0}
\newcommand{\NDPRefPoint}{c}
\newcommand{\NDPputRotation}{0}
\newcommand{\NumDataPlotBuffer}{0}
\newcommand{\NumDataPlotBufferI}{0}
\newcommand{\TicksXRight}{0}
\newcommand{\TicksXLeft}{0}
\newcommand{\TicksYRight}{0}
\newcommand{\TicksYLeft}{0}
\newcommand{\TickLabelsXRight}{0}
\newcommand{\TickLabelsXLeft}{0}
\newcommand{\TickLabelsYRight}{0}
\newcommand{\TickLabelsYLeft}{0}
\newcommand{\xTickLength}{-10}
\newcommand{\yTickLength}{-10}
\newcommand{\xNrTicks}{1}
\newcommand{\yNrTicks}{1}
\newcommand{\xNrTickLabels}{1}
\newcommand{\yNrTickLabels}{1}
\newboolean{PlotLeftAxis}
\setboolean{PlotLeftAxis}{true}
\newboolean{PlotRightAxis}
\setboolean{PlotRightAxis}{true}
\newboolean{PlotLowerAxis}
\setboolean{PlotLowerAxis}{true}
\newboolean{PlotUpperAxis}
\setboolean{PlotUpperAxis}{true}
\newcommand{\nrLegendCols}{1}
\newlength{\LegLineWidth}\setlength{\LegLineWidth}{20pt}
\newboolean{LegendOrientationLeft}
\newboolean{LegendOrientationRight}
\newboolean{LegendOrientationCenter}
\setboolean{LegendOrientationLeft}{true}
\setboolean{LegendOrientationRight}{false}
\setboolean{LegendOrientationCenter}{false}
\newcommand{\LogxAxis}{}
\newcommand{\LogxAxisLabel}[1]{$#1$}
\newcommand{\LogyAxis}{}
\newcommand{\LogyAxisLabel}[1]{$#1$}
\newcounter{BufferCounter}
% ----------------------------------------------------------------------------
% | define keys for the axis style etc.
% ----------------------------------------------------------------------------
% define some command keys
% the command keys only save the provided value in \NumDataPlot for later
% use. The standard values for the command keys are set at the end of the
% package.
\define@cmdkeys[NumericDataPlot]{Axis}[NumDataPlot]
{xMax, xMin,
Dx,
dx, % so far, these are always calculated and cannot be set by user
xCoordMax, xCoordMin,
yMax, yMin,
Dy,
dy, % so far, these are always calculated and cannot be set by user
yCoordMax, yCoordMin
}
\define@boolkey[NumericDataPlot]{Axis}{xLog}[true]{
\ifNumericDataPlot@Axis@xLog
\renewcommand{\LogxAxis}{log}
\renewcommand{\LogxAxisLabel}[1]{
\ifthenelse{##1<1}{
\ifthenelse{##1>-1}{%
$10^{0}$%
}{%
$10^{##1}$%
}}%
{%
$10^{##1}$%
}%
}%
\else
\renewcommand{\LogxAxis}{}
\renewcommand{\LogxAxisLabel}[1]{$##1$}
\fi
}
\define@boolkey[NumericDataPlot]{Axis}{yLog}[true]{
\ifNumericDataPlot@Axis@yLog
\renewcommand{\LogyAxis}{log}
\renewcommand{\LogyAxisLabel}[1]{
\ifthenelse{##1<1}{
\ifthenelse{##1>-1}{%
$10^{0}$%
}{%
$10^{##1}$%
}}%
{%
$10^{##1}$%
}%
}%
\else
\renewcommand{\LogyAxis}{}
\renewcommand{\LogyAxisLabel}[1]{$##1$}
\fi
}
\define@boolkey[NumericDataPlot]{Axis}{xLogNoSubGrid}[true]{
}
\define@boolkey[NumericDataPlot]{Axis}{yLogNoSubGrid}[true]{
}
\define@boolkey[NumericDataPlot]{Axis}{yNearlyTight}[false]{}
% xMin and yMin also set xO/yO. It will later be ensured that if the user
% provides a value for xO/yO, these values will be used! (in order to do so, it
% is always necessary to call the following two commands in the given order:
% \setkeys[NumericDataPlot]{Axis}{}
% \setrmkeys[NumericDataPlot]{AxisWait}
% where can contain all the keys from Axis and from AxisWait)
% same goes for DDy and DDx (Dy for labels): By default, the values of dy and dx
% will be used.
\define@cmdkeys[NumericDataPlot]{AxisWait}[NumDataPlot]{xO, yO, DDy, DDx}{}
\define@boolkeys[NumericDataPlot]{xAxis}
{NoGrid, NoTicks, NoLabel, NoTickLabel}[true]
\define@boolkeys[NumericDataPlot]{yAxis}
{NoGrid, NoTicks, NoLabel, NoTickLabel}[true]
\define@choicekey+[NumericDataPlot]{xAxis}{AxisStyle}[\val\nrAxisStyle]
{Boxed,Lower,Upper,None}{
\ifcase\nrAxisStyle\relax
\setboolean{PlotLowerAxis}{true}
\setboolean{PlotUpperAxis}{true}
\or
\setboolean{PlotLowerAxis}{true}
\setboolean{PlotUpperAxis}{false}
\or
\setboolean{PlotLowerAxis}{false}
\setboolean{PlotUpperAxis}{true}
\or
\setboolean{PlotLowerAxis}{false}
\setboolean{PlotUpperAxis}{false}
\fi
}{
\PackageWarning{NumericPlots}
{AxisStyle #1 not defined. Use Boxed, Lower, Upper or None}
}
\define@choicekey+[NumericDataPlot]{yAxis}{AxisStyle}[\val\nrAxisStyle]
{Boxed,Right,Left,None}{
\ifcase\nrAxisStyle\relax
\setboolean{PlotRightAxis}{true}
\setboolean{PlotLeftAxis}{true}
\or
\setboolean{PlotRightAxis}{true}
\setboolean{PlotLeftAxis}{false}
\or
\setboolean{PlotRightAxis}{false}
\setboolean{PlotLeftAxis}{true}
\or
\setboolean{PlotRightAxis}{false}
\setboolean{PlotLeftAxis}{false}
\fi
}{
\PackageWarning{NumericPlots}
{AxisStyle #1 not defined. Use Boxed, Right, Left or None}
}
% ----------------------------------------------------------------------------
% | general keys
% |
% | picture width etc.
% ----------------------------------------------------------------------------
\define@cmdkeys[NumericDataPlot]{General}[NumDataPlotG]{%
xPicMin, yPicMin, xPicMax, yPicMax, TickLength%
}
\define@key[NumericDataPlot]{General}{llx}[\StdLLX]{%
\psset{llx=-#1}%
\addtolength{\OffsetWidth}{-\StdLLX}%
\addtolength{\OffsetWidth}{#1}%
}
\define@key[NumericDataPlot]{General}{urx}[\StdURX]{%
\psset{urx=#1}%
\addtolength{\OffsetWidth}{-\StdURX}%
\addtolength{\OffsetWidth}{#1}%
}
\define@key[NumericDataPlot]{General}{lly}[\StdLLY]{%
\psset{lly=-#1}%
\addtolength{\OffsetHeight}{-\StdLLY}%
\addtolength{\OffsetHeight}{#1}%
}
\define@key[NumericDataPlot]{General}{ury}[\StdURY]{%
\psset{ury=#1}%
\addtolength{\OffsetHeight}{-\StdURY}%
\addtolength{\OffsetHeight}{#1}%
}
% ------------------------------------------------------------------------------
% | keys for the put commands
% ------------------------------------------------------------------------------
\define@key[NumericDataPlot]{put}{x}{
\FPsub{\NumDataPlotBuffer}{#1}{\NumDataPlotxMin}
\FPmul{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotxDataCoordRatio}
\FPadd{\NDPputXcoord}{\NumDataPlotBuffer}{\NumDataPlotxCoordMin}
}
\define@key[NumericDataPlot]{put}{y}{
\FPsub{\NumDataPlotBuffer}{#1}{\NumDataPlotyMin}
\FPmul{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotyDataCoordRatio}
\FPadd{\NDPputYcoord}{\NumDataPlotBuffer}{\NumDataPlotyCoordMin}
}
\define@key[NumericDataPlot]{put}{RefPoint}[c]{
\renewcommand{\NDPRefPoint}{#1}
}
\define@key[NumericDataPlot]{put}{Rot}[0]{
\renewcommand{\NDPputRotation}{#1}
}
%-------------------------------------------------------------------------------
\input{NumericPlots_labels}
\input{NumericPlots_TickLabels}
%
%\newlength{\picwidth}
\newlength{\CPicWidth}
\newlength{\CPicHeight}
\newlength{\StdLLX}\setlength{\StdLLX}{7ex +\baselineskip+2pt}
\newlength{\StdLLY}\setlength{\StdLLY}{2\baselineskip+1ex+2pt}
\newlength{\StdURX}\setlength{\StdURX}{2ex}
\newlength{\StdURY}\setlength{\StdURY}{0.5em}
\newlength{\OffsetWidth}
\newlength{\OffsetHeight}
% ==============================================================================
% ||
% || Axis (Scaling)
% ||
% ==============================================================================
\newcommand{\ScaleAxes}{
% calculate scaling:
% ( - xMin) * xDataCoordRatio + xCoordMin
% ( - yMin) * yDataCoordRatio + yCoordMin
% DataCoordRatio = (CoordMax-CoordMin)/(Max-Min)
% for logarithmic axes:
% (log() - log(xMin)) * xDataCoordRatio + xCoordMin
% (log() - log(yMin)) * yDataCoordRatio + yCoordMin
% DataCoordRatio = (CoordMax-CoordMin)/(log(Max)-log(Min))
\renewcommand{\xScaling}{\LogxAxis\space \NumDataPlotxMin\space sub
\NumDataPlotxDataCoordRatio\space mul \NumDataPlotxCoordMin\space add}
\renewcommand{\yScaling}{\LogyAxis\space \NumDataPlotyMin\space sub
\NumDataPlotyDataCoordRatio\space mul \NumDataPlotyCoordMin\space add}
\pstScalePoints(1.0, 1.0){\xScaling}{\yScaling}
}
% ==============================================================================
% ||
% || x-Axis
% ||
% ==============================================================================
\newcommand{\setxAxis}[1]{
% set the keys. xO and yO have to be set after xMin and yMin have been set!
% (xMin and yMin also set xO and yO but when xO and yO are set by the user,
% these values should be overwritten.)
\setkeys*[NumericDataPlot]{Axis}
[yMin, yMax, Dy, dy, yCoordMin, yCoordMax, yLog]{#1}
\setrmkeys[NumericDataPlot]{AxisWait}[yO, DDy]
% for logarithmic axes: calculate log(xMax), log(xMin), Dx=1, xO=ceil(xMin)
\ifNumericDataPlot@Axis@xLog
\FPln{\NumDataPlotBuffer}{\NumDataPlotxMax}
\FPdiv{\NumDataPlotxMax}{\NumDataPlotBuffer}{\NumDataPlotLnTen}
\FPround{\NumDataPlotxMax}{\NumDataPlotxMax}{3}
\FPln{\NumDataPlotBuffer}{\NumDataPlotxMin}
\FPdiv{\NumDataPlotxMin}{\NumDataPlotBuffer}{\NumDataPlotLnTen}
\FPround{\NumDataPlotxMin}{\NumDataPlotxMin}{3}
\renewcommand{\NumDataPlotDx}{1}
\FPtrunc{\NumDataPlotBuffer}{\NumDataPlotxMin}{0}
\FPadd{\NumDataPlotxO}{\NumDataPlotBuffer}{1}
\FPround{\NumDataPlotxO}{\NumDataPlotBuffer}{0}
\fi
\FPsub{\NumDataPlotxRange}{\NumDataPlotxMax}{\NumDataPlotxMin}
\FPsub{\NumDataPlotxCoordRange}{\NumDataPlotxCoordMax}{\NumDataPlotxCoordMin}
\FPdiv{\NumDataPlotxDataCoordRatio}{\NumDataPlotxCoordRange}{\NumDataPlotxRange}
% calculate number of ticks
\FPdiv{\xNrTicks}{\NumDataPlotxRange}{\NumDataPlotDx}
\FPtrunc{\xNrTicks}{\xNrTicks}{0}
% calculate number of tick labels
\FPdiv{\xNrTickLabels}{\NumDataPlotxRange}{\NumDataPlotDDx}
\FPtrunc{\xNrTickLabels}{\xNrTickLabels}{0}
% calculate dx (distance (in coordinates) between two ticks)
\FPmul{\NumDataPlotdx}{\NumDataPlotxDataCoordRatio}{\NumDataPlotDx}
\FPround{\NumDataPlotdx}{\NumDataPlotdx}{2}
% calculate dx for labels
\FPmul{\NumDataPlotdxLabels}{\NumDataPlotxDataCoordRatio}{\NumDataPlotDDx}
\FPround{\NumDataPlotdxLabels}{\NumDataPlotdxLabels}{2}
% calculate coordinates of x origin
\FPsub{\NumDataPlotBuffer}{\NumDataPlotxO}{\NumDataPlotxMin}
\FPmul{\NumDataPlotBuffer}{\NumDataPlotxDataCoordRatio}{\NumDataPlotBuffer}
\FPadd{\xCoordOrig}{\NumDataPlotBuffer}{\NumDataPlotxCoordMin}
\FPround{\xCoordOrig}{\xCoordOrig}{2}
% calculate number of ticks on right side of the origin
\FPsub{\TicksXRight}{\NumDataPlotxMax}{\NumDataPlotxO}
\FPdiv{\TicksXRight}{\TicksXRight}{\NumDataPlotDx}
\FPtrunc{\TicksXRight}{\TicksXRight}{0}
% calculate number of tick labels on right side of the origin
\FPsub{\TickLabelsXRight}{\NumDataPlotxMax}{\NumDataPlotxO}
\FPdiv{\TickLabelsXRight}{\TickLabelsXRight}{\NumDataPlotDDx}
\FPtrunc{\TickLabelsXRight}{\TickLabelsXRight}{0}
% calculate number of ticks on left side of the origin (number is negative!)
\FPsub{\TicksXLeft}{\NumDataPlotxMin}{\NumDataPlotxO}
\FPdiv{\TicksXLeft}{\TicksXLeft}{\NumDataPlotDx}
\FPsub{\TicksXLeft}{\TicksXLeft}{1}
\FPtrunc{\TicksXLeft}{\TicksXLeft}{0}
% calculate number of tick labels on left side of the origin (number is
% negative!)
\FPsub{\TickLabelsXLeft}{\NumDataPlotxMin}{\NumDataPlotxO}
\FPdiv{\TickLabelsXLeft}{\TickLabelsXLeft}{\NumDataPlotDDx}
\FPsub{\TickLabelsXLeft}{\TickLabelsXLeft}{1}
\FPtrunc{\TickLabelsXLeft}{\TickLabelsXLeft}{0}
\ScaleAxes{}
}
\newcommand{\plotxGridLine}[1]{
\FPsub{\NumDataPlotBuffer}{\NumDataPlotxCoordMax}{#1}
\FPsub{\NumDataPlotBufferI}{#1}{\NumDataPlotxCoordMin}
\FPmin{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotBufferI}
% \FPifneg{\NumDataPlotBuffer}
% \else
% plot grid line
\ifNumericDataPlot@xAxis@NoGrid
\else
\psline[style=GridSt](#1, \NumDataPlotyCoordMin)(#1, \NumDataPlotyCoordMax)
\fi
% plot tick for lower axis and upper axis - if desired
\ifNumericDataPlot@xAxis@NoTicks
\else
\ifthenelse{\boolean{PlotLowerAxis}}{
\psline[style=TickSt](#1, \NumDataPlotyCoordMin)
(!#1\space \NumDataPlotyCoordMin\space \xTickLength \space sub)
}{}
\ifthenelse{\boolean{PlotUpperAxis}}{
\psline[style=TickSt](#1, \NumDataPlotyCoordMax)
(!#1 \NumDataPlotyCoordMax\space \xTickLength \space add)
}{}
\fi
% \fi
}
\newcommand{\plotxSubGridLine}[1]{
\FPsub{\NumDataPlotBuffer}{\NumDataPlotxCoordMax}{#1}
\FPsub{\NumDataPlotBufferI}{#1}{\NumDataPlotxCoordMin}
\FPmin{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotBufferI}
\FPifneg{\NumDataPlotBuffer}
\else
% plot grid line
\ifNumericDataPlot@xAxis@NoGrid
\else
\psline[style=GridSt](#1,\NumDataPlotyCoordMin)(#1,\NumDataPlotyCoordMax)
\fi
\fi
}
% for logarithmic axes, LogxAxisLabel returns 10^#1. Normally it just returns
% #1.
\newcommand{\plotxTickLabels}[1]{
\FPadd{\NumDataPlotBuffer}{\TickLabelsXLeft}{1}
\FPround{\NumDataPlotBuffer}{\NumDataPlotBuffer}{0}
% plot ticks on right side of the origin
\mmultido{\n=\NumDataPlotxO+\NumDataPlotDDx}{\TickLabelsXRight}
{
\PutTickLabelXaxis[#1,x=\n]{\LogxAxisLabel{\n}}
}
% plot ticks on left side of the origin
\mmultido{\n=\NumDataPlotxO+\NumDataPlotDDx}{\NumDataPlotBuffer}
{
\PutTickLabelXaxis[#1,x=\n]{\LogxAxisLabel{\n}}
}
% plot tick at origin
\PutTickLabelXaxis[#1,x=\NumDataPlotxO]{\LogxAxisLabel{\NumDataPlotxO}}
}
\newcommand{\xLogSubGrid}[1]{
\ifNumericDataPlot@Axis@xLogNoSubGrid
\else
\ifNumericDataPlot@Axis@xLog
\multido{\iSubb=2+1}{8}{
\FPln{\NumDataPlotBuffer}{\iSubb}
\FPdiv{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotLnTen}
\FPmul{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotxDataCoordRatio}
\FPadd{\NumDataPlotTickPos}{#1}{\NumDataPlotBuffer}
\plotxSubGridLine{\NumDataPlotTickPos}
}
\fi
\fi
}
\newcommand{\plotxGrid}[1][NoGrid=false]{
\setkeys*[NumericDataPlot]{xAxis}{#1}
% plot gridline on right side of the origin
\mmultido{\n=\xCoordOrig+\NumDataPlotdx}{\TicksXRight}{
\plotxGridLine{\n}
\xLogSubGrid{\n}
}
% plot gridline on left side of the origin and at origin
\multido{\n=\xCoordOrig+\NumDataPlotdx}{\TicksXLeft}{
\plotxGridLine{\n}
}
\FPsub{\NumDataPlotBuffer}{\TicksXLeft}{1}
\FPround{\NumDataPlotBuffer}{\NumDataPlotBuffer}{0}
\multido{\n=\xCoordOrig+\NumDataPlotdx}{\NumDataPlotBuffer}{
\xLogSubGrid{\n}
}
}
\newcommand{\plotxAxis}[2][]{
\setkeys[NumericDataPlot]{putxLabel}{LabelSep}
\setkeys*[NumericDataPlot]{putxLabel}{#1}
\setrmkeys*[NumericDataPlot]{putxTickLabel}
\setrmkeys[NumericDataPlot]{xAxis}
% plot grid, ticks and ticklabels
\plotxGrid[#1]
% plot lower axis
\ifthenelse{\boolean{PlotLowerAxis}}
{
\psline{C-C}%
(\NumDataPlotxCoordMin, \NumDataPlotyCoordMin)%
(\NumDataPlotxCoordMax, \NumDataPlotyCoordMin)
\ifNumericDataPlot@xAxis@NoTickLabel
\else
\plotxTickLabels{ax=lower,#1}
\fi
% plot label
\ifNumericDataPlot@xAxis@NoLabel
\else
\PutLabelXaxis[ax=lower,#1]{#2}
\fi
%plot upper axis (boxed)
\ifthenelse{\boolean{PlotUpperAxis}}{
% plot upper axis
\psline{C-C}%
(\NumDataPlotxCoordMin,\NumDataPlotyCoordMax)%
(\NumDataPlotxCoordMax,\NumDataPlotyCoordMax)
}{}
}{
% plot upper axis (only upper axis)
\ifthenelse{\boolean{PlotUpperAxis}}{
% plot upper axis
\psline{C-C}%
(\NumDataPlotxCoordMin,\NumDataPlotyCoordMax)%
(\NumDataPlotxCoordMax, \NumDataPlotyCoordMax)
% plot ticklabels
\ifNumericDataPlot@xAxis@NoTickLabel
\else
\plotxTickLabels{ax=upper,#1}
\fi
% plot label
\ifNumericDataPlot@xAxis@NoLabel
\else
\PutLabelXaxis[ax=upper,#1]{#2}
\fi
}{}
}
}
\newcommand{\repeatxAxis}{\plotxAxis[NoLabel, NoTickLabel]{}}
% ==============================================================================
% ||
% || y-Axis
% ||
% ==============================================================================
\newcommand{\plotyTickLabels}[1]{
\FPadd{\NumDataPlotBuffer}{\TickLabelsYLeft}{1}
\FPround{\NumDataPlotBuffer}{\NumDataPlotBuffer}{0}
% plot ticks on right side of the origin
\mmultido{\n=\NumDataPlotyO+\NumDataPlotDDy}{\TickLabelsYRight}
{
\PutTickLabelYaxis[#1,y=\n]{\LogyAxisLabel{\n}}
}
% plot ticks on left side of the origin
\mmultido{\n=\NumDataPlotyO+\NumDataPlotDDy}{\NumDataPlotBuffer}
{
\PutTickLabelYaxis[#1,y=\n]{\LogyAxisLabel{\n}}
}
% plot tick at origin
\PutTickLabelYaxis[#1,y=\NumDataPlotyO]{\LogyAxisLabel{\NumDataPlotyO}}
}
\newcommand{\setyAxis}[1]{
% values from the x-axis must be ignored! If they weren't, the default values
% would be set!
\setkeys*[NumericDataPlot]{Axis}
[xO, xMin, xMax, xCoordMin, xCoordMax, Dx, dx, xLog]{#1}
\setrmkeys[NumericDataPlot]{AxisWait}[xO, DDx]
%\ifNumericDataPlot@Axis@yNearlyTight
% \FPifpos{\NumDataPlotyMax} \FPmul{\NumDataPlotyMax}{\NumDataPlotyMax}{1.1} \else \FPmul{\NumDataPlotyMax}{\NumDataPlotyMax}{0.9}\fi
% \FPifpos{\NumDataPlotyMin} \FPmul{\NumDataPlotyMin}{\NumDataPlotyMin}{0.9} \else \FPmul{\NumDataPlotyMin}{\NumDataPlotyMin}{1.1}\fi
% \fi
% for logarithmic axes: calculate log(xMax), log(xMin), Dy=1, xO=ceil(xMin)
\ifNumericDataPlot@Axis@yLog
\FPln{\NumDataPlotBuffer}{\NumDataPlotyMax}
\FPdiv{\NumDataPlotyMax}{\NumDataPlotBuffer}{\NumDataPlotLnTen}
\FPround{\NumDataPlotyMax}{\NumDataPlotyMax}{6}
\FPln{\NumDataPlotBuffer}{\NumDataPlotyMin}
\FPdiv{\NumDataPlotyMin}{\NumDataPlotBuffer}{\NumDataPlotLnTen}
\FPround{\NumDataPlotyMin}{\NumDataPlotyMin}{6}
\renewcommand{\NumDataPlotDy}{1}
\FPtrunc{\NumDataPlotBuffer}{\NumDataPlotyMin}{0}
\FPadd{\NumDataPlotyO}{\NumDataPlotBuffer}{1}
\FPround{\NumDataPlotyO}{\NumDataPlotyO}{0}
\fi
\FPsub{\NumDataPlotyRange}{\NumDataPlotyMax}{\NumDataPlotyMin}
\FPsub{\NumDataPlotyCoordRange}{\NumDataPlotyCoordMax}{\NumDataPlotyCoordMin}
\FPdiv{\NumDataPlotyDataCoordRatio}{\NumDataPlotyCoordRange}{\NumDataPlotyRange}
% calculate number of ticks
\FPdiv{\yNrTicks}{\NumDataPlotyRange}{\NumDataPlotDy}
\FPtrunc{\yNrTicks}{\yNrTicks}{0}
% calculate number of tick labels
\FPdiv{\yNrTickLabels}{\NumDataPlotyRange}{\NumDataPlotDDy}
\FPtrunc{\yNrTickLabels}{\yNrTickLabels}{0}
% calculate dy in coord -> distance between two ticks
\FPmul{\NumDataPlotdy}{\NumDataPlotyDataCoordRatio}{\NumDataPlotDy}
\FPround{\NumDataPlotdy}{\NumDataPlotdy}{2}
% calculate dyLabels in coord -> distance between two tick labels
\FPmul{\NumDataPlotdyLabels}{\NumDataPlotyDataCoordRatio}{\NumDataPlotDDy}
\FPround{\NumDataPlotdyLabels}{\NumDataPlotdyLabels}{2}
% calculate coordinates of y origin
\FPsub{\NumDataPlotBuffer}{\NumDataPlotyO}{\NumDataPlotyMin}
\FPmul{\NumDataPlotBuffer}{\NumDataPlotyDataCoordRatio}{\NumDataPlotBuffer}
\FPadd{\yCoordOrig}{\NumDataPlotBuffer}{\NumDataPlotyCoordMin}
\FPround{\yCoordOrig}{\yCoordOrig}{2}
% calculate number of ticks on right side of the origin
\FPsub{\TicksYRight}{\NumDataPlotyMax}{\NumDataPlotyO}
\FPdiv{\TicksYRight}{\TicksYRight}{\NumDataPlotDy}
\FPtrunc{\TicksYRight}{\TicksYRight}{0}
% calculate number of tick labels on right side of the origin
\FPsub{\TickLabelsYRight}{\NumDataPlotyMax}{\NumDataPlotyO}
\FPdiv{\TickLabelsYRight}{\TickLabelsYRight}{\NumDataPlotDDy}
\FPtrunc{\TickLabelsYRight}{\TickLabelsYRight}{0}
% calculate number of ticks on left side of the origin (number is negative!)
\FPsub{\TicksYLeft}{\NumDataPlotyMin}{\NumDataPlotyO}
\FPdiv{\TicksYLeft}{\TicksYLeft}{\NumDataPlotDy}
\FPsub{\TicksYLeft}{\TicksYLeft}{1}
\FPtrunc{\TicksYLeft}{\TicksYLeft}{0}
% calculate number of tick labels on left side of the origin (number is
% negative!)
\FPsub{\TickLabelsYLeft}{\NumDataPlotyMin}{\NumDataPlotyO}
\FPdiv{\TickLabelsYLeft}{\TickLabelsYLeft}{\NumDataPlotDDy}
\FPsub{\TickLabelsYLeft}{\TickLabelsYLeft}{1}
\FPtrunc{\TickLabelsYLeft}{\TickLabelsYLeft}{0}
% --- scaling ---
\ScaleAxes{}
}
\newcommand{\plotyGridLine}[1]{%
\FPsub{\NumDataPlotBuffer}{\NumDataPlotyCoordMax}{#1}
\FPsub{\NumDataPlotBufferI}{#1}{\NumDataPlotyCoordMin}
\FPmin{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotBufferI}
\FPifpos{\NumDataPlotBuffer}
% plot grid line
\ifNumericDataPlot@yAxis@NoGrid
\else
\psline[style=GridSt](\NumDataPlotxCoordMin, #1)(\NumDataPlotxCoordMax, #1)
\fi
% plot tick for lower axis and upper axis - if desired
\ifNumericDataPlot@yAxis@NoTicks
\else
\ifthenelse{\boolean{PlotLeftAxis}}{
\psline[style=TickSt](\NumDataPlotxCoordMin, #1)
(!\NumDataPlotxCoordMin\space \yTickLength \space sub #1)
}{}
\ifthenelse{\boolean{PlotRightAxis}}{
\psline[style=TickSt](\NumDataPlotxCoordMax, #1)
(!\NumDataPlotxCoordMax\space \yTickLength \space add #1)
}{}
\fi
\fi
}
\newcommand{\plotySubGridLine}[1]{%
% only used by yLogSubGrid
\FPsub{\NumDataPlotBuffer}{\NumDataPlotyCoordMax}{#1}
\FPsub{\NumDataPlotBufferI}{#1}{\NumDataPlotyCoordMin}
\FPmin{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotBufferI}
\FPifpos{\NumDataPlotBuffer}
% plot grid line
\ifNumericDataPlot@yAxis@NoGrid
\else
\psline[style=GridSt](\NumDataPlotxCoordMin, #1)(\NumDataPlotxCoordMax, #1)
\fi
\fi
}
\newcommand{\yLogSubGrid}[1]{%
% plots the subgrid for logarithmic axes, i.e. the grid between the two lines
% 10^x and 10^(x+1)
\ifNumericDataPlot@Axis@yLogNoSubGrid
\else
\ifNumericDataPlot@Axis@yLog
\multido{\iSubb=2+1}{8}{
\FPln{\NumDataPlotBuffer}{\iSubb}
\FPdiv{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotLnTen}
\FPmul{\NumDataPlotBuffer}{\NumDataPlotBuffer}{\NumDataPlotyDataCoordRatio}
\FPadd{\NumDataPlotTickPos}{#1}{\NumDataPlotBuffer}
\plotySubGridLine{\NumDataPlotTickPos}
}
\fi
\fi
}
\newcommand{\plotyGrid}[1][NoGrid=false]{
\setkeys*[NumericDataPlot]{yAxis}{#1}
% plot gridline on right side of the origin
\mmultido{\n=\yCoordOrig+\NumDataPlotdy}{\TicksYRight}{
\plotyGridLine{\n}
\yLogSubGrid{\n}
}
% plot gridline on left side of the origin
\multido{\n=\yCoordOrig+\NumDataPlotdy}{\TicksYLeft}{
\plotyGridLine{\n}
}
\FPsub{\NumDataPlotBuffer}{\TicksYLeft}{1}
\FPround{\NumDataPlotBuffer}{\NumDataPlotBuffer}{0}
\multido{\n=\yCoordOrig+\NumDataPlotdy}{\NumDataPlotBuffer}{
\yLogSubGrid{\n}
}
}
\newcommand{\plotyGridBoxed}{
% plot gridline on right side of the origin
\mmultido{\n=\yCoordOrig+\NumDataPlotdy}{\TicksYRight-1}{
\plotyGridLine{\n}
\yLogSubGrid{\n}
}
% plot gridline on left side of the origin
\multido{\n=\yCoordOrig+\NumDataPlotdy}{\TicksYLeft-1}{
\plotyGridLine{\n}
}
\FPsub{\NumDataPlotBuffer}{\TicksYLeft}{1}
\FPround{\NumDataPlotBuffer}{\NumDataPlotBuffer}{0}
\multido{\n=\yCoordOrig+\NumDataPlotdy}{\NumDataPlotBuffer}{
\yLogSubGrid{\n}
}
}
\newcommand{\plotyAxis}[2][]{
\setkeys[NumericDataPlot]{putyLabel}{LabelSep}
\setkeys*[NumericDataPlot]{putyLabel}{#1}
\setrmkeys*[NumericDataPlot]{putyTickLabel}
\setrmkeys[NumericDataPlot]{yAxis}
% plot grid
\plotyGrid[#1]
% plot left axis
\ifthenelse{\boolean{PlotLeftAxis}}
{
\psline{C-C}%
(\NumDataPlotxCoordMin,\NumDataPlotyCoordMin)%
(\NumDataPlotxCoordMin, \NumDataPlotyCoordMax)
\ifNumericDataPlot@yAxis@NoTickLabel
\else
\plotyTickLabels{ax=left,#1}
\fi
% plot right axis
\ifthenelse{\boolean{PlotRightAxis}}
{
\psline{C-C}%
(\NumDataPlotxCoordMax,\NumDataPlotyCoordMin)%
(\NumDataPlotxCoordMax, \NumDataPlotyCoordMax)
}{}
% --- label ---
\ifNumericDataPlot@yAxis@NoLabel
\else
\PutLabelYaxis[ax=left,#1]{#2}
\fi
}{
\ifthenelse{\boolean{PlotRightAxis}}
{
\psline{C-C}%
(\NumDataPlotxCoordMax,\NumDataPlotyCoordMin)%
(\NumDataPlotxCoordMax, \NumDataPlotyCoordMax)
\ifNumericDataPlot@yAxis@NoTickLabel
\else
\plotyTickLabels{ax=right,#1}
\fi
% --- label ---
\ifNumericDataPlot@yAxis@NoLabel
\else
\PutLabelYaxis[ax=right,#1]{#2}
\fi
}{}
}
}
% ==============================================================================
% ||
% || environment NumericDataPlot
% ||
% ==============================================================================
\newenvironment{NumericDataPlot}[3][]{%
%
\setlength{\OffsetWidth}{+\StdLLX +\StdURX}%
\setlength{\OffsetHeight}{+\StdLLY +\StdURY}%
% set standard values (they will be reset by setkeys if defined)
\psset{llx=-\StdLLX, lly=-\StdLLY, ury=\StdURY, urx=\StdURX}%
%
\setkeys[NumericDataPlot]{General}{#1}%
%
\setlength{\CPicWidth}{#2 - \OffsetWidth}%
\setlength{\CPicHeight}{#3 - \OffsetHeight}%
%%\setlength{\CPicWidth}{#2}
% calculate length of the yTicks:
% PicCoordWidth (=GxPicMax-GxPicMin) -> PicWidth (=#2)
% Length -> 1mm * yTickLength
% yTickLength must be negative
\setcounter{BufferCounter}{1*\ratio{#2}{1mm}}%
\FPsub{\NumDataPlotBuffer}{\NumDataPlotGxPicMax}{\NumDataPlotGxPicMin}%
\FPdiv{\NumDataPlotBufferI}{\NumDataPlotBuffer}{\theBufferCounter}%
\FPmul{\yTickLength}{\NumDataPlotBufferI}{\NumDataPlotGTickLength}%
\FPmul{\yTickLength}{\NumDataPlotBufferI}{-1}%
% calculate length of the xTicks
\setcounter{BufferCounter}{1*\ratio{#3}{1mm}}%
\FPsub{\NumDataPlotBuffer}{\NumDataPlotGyPicMax}{\NumDataPlotGyPicMin}%
\FPdiv{\NumDataPlotBufferI}{\NumDataPlotBuffer}{\theBufferCounter}%
\FPmul{\xTickLength}{\NumDataPlotBufferI}{\NumDataPlotGTickLength}%
\FPmul{\xTickLength}{\NumDataPlotBufferI}{-1}%
%
\begin{psgraph}%
[fillstyle=solid, fillcolor=gray, xAxis=false, yAxis=false]%
(\NumDataPlotGxPicMin, \NumDataPlotGyPicMin)(\NumDataPlotGxPicMin, \NumDataPlotGyPicMin)(\NumDataPlotGxPicMax, \NumDataPlotGyPicMax)%
{\CPicWidth}{\CPicHeight}%
}{%
\pstScalePoints(1.0, 1.0){0 add}{0 add}%
\end{psgraph}%
}
\psset{xunit=1mm, yunit=1mm, xAxisLabel={}, yAxisLabel={}}%
%
% ==============================================================================
% ||
% || legend
% ||
% ==============================================================================
\input{NumericPlots_legend}
% ============================================================================
% ||
% || Definition of styles
% ||
% ============================================================================
\input{NumericPlots_styles}
% ==============================================================================
% ||
% || commands...
% ||
% ==============================================================================
\input{NumericPlots_macros}
% ==============================================================================
% ||
% || package options ...
% ||
% ==============================================================================
\DeclareOptionX{beamer}{
\renewcommand{\StdLLY}{1.0cm}%
\renewcommand{\StdTickLabelOption}{\footnotesize}%
\setlength{\origXLabelSep}{1pt}%
}
\DeclareOptionX{xAxisStyle}[Boxed]{%
\presetkeys[NumericDataPlot]{xAxis}{AxisStyle=#1}{}%
}
\DeclareOptionX{yAxisStyle}[Boxed]{%
\presetkeys[NumericDataPlot]{yAxis}{AxisStyle=#1}{}%
}
\DeclareOptionX{LabelOption}[{}]{%
\renewcommand{\StdLabelOption}{#1}%
}
\DeclareOptionX{TickLabelOption}[{}]{%
\renewcommand{\StdTickLabelOption}{#1}%
}
\ProcessOptionsX
% \ProcessOptions
% ===========================================================================
% ||
% || set standard values for keys
% ||
% ===========================================================================
\presetkeys[NumericDataPlot]{Axis}{
xMax=100, xMin=0, Dx=10,
xCoordMax=\NumDataPlotGxPicMax, xCoordMin=\NumDataPlotGxPicMin,
xLog=false,
yMax=100, yMin=0, Dy=10,
yCoordMax=\NumDataPlotGyPicMax, yCoordMin=\NumDataPlotGyPicMin,
yLog=false,
yNearlyTight=false
}{}
\presetkeys[NumericDataPlot]{xAxis}{
NoGrid=false, NoTicks=false, NoLabel=false, NoTickLabel=false
}{}
\presetkeys[NumericDataPlot]{yAxis}{
NoGrid=false, NoTicks=false, NoLabel=false, NoTickLabel=false
}{}
% if xO/yO are not set they'll be set to xMin/yMin
\presetkeys[NumericDataPlot]{AxisWait}{%
xO=\NumDataPlotxMin, yO=\NumDataPlotyMin,%
DDx=\NumDataPlotDx, DDy=\NumDataPlotDy%
}{}
\presetkeys[NumericDataPlot]{General}{%
xPicMin=0, yPicMin=0, xPicMax=1000, yPicMax=1000, TickLength=2}{}%
\presetkeys[NumericDataPlot]{Legend}{%
LabelOrientation=l%
}{}%