Fondo
Supongamos que tiene datos como estos en la sección de datos de datavisualization
, que también podrían provenir de un archivo,
date,birds
30/10/2023,1200
02/10/2023,1229
...
o
species,birds
spec4,1200
spec1,1229
...
\datavisualization
proporciona dos visualizaciones, scientific axes
y school book axes
, que requieren datos xy.
Pregunta
No es gran cosa reemplazar los datos x textuales por un contador, para introducir una escala ordinal simple. Pero, ¿cómo conservar o acceder a los datos x originales Y ponerlos como etiquetas en el eje x en lugar de 1,2,...?
Intentos
El siguiente código proporciona \pgfdeclaredataformat{ordinalX}
, que reemplaza x-data por un simple contador NX.
Sé que yopodríaescriba una lista, por ejemplo, a través de ticks={major at={1 as spec4,...}}
, a mano en la declaración del eje x. Pero esa no es una buena idea cuando se procesan datos, como ya se mencionó en la sección de datos.
Parece que no tengo idea sobre el alcance de los datos, el acceso, las estructuras de datos utilizadas aquí o incluso adivinar la pgfkey correcta solo del pgfmanual wrt datavisualization
.
¿Esto sólo se puede resolver introduciendo una variable global, por ejemplo, como pgfkeys, l3, "array", objeto de datos, etc.? Y si es así, ¿el formato declarado colocará allí los datos x originales extraídos?
\documentclass[10pt,border=3mm,tikz]{standalone}
\usetikzlibrary{datavisualization}
\newcounter{NX}
% ~~~ introducing ordinal values for x ~~~~~~~~~
% converts (date,birds) into (NX,birds) in (x,y) world
\pgfdeclaredataformat{ordinalX}
{}
{}
{#1,#2}
{ % ~~~ new x-values: one-by-one ~~~~~~~~~
\pgfmathaddtocounter{NX}{1}
\pgfkeyssetvalue{/data point/x}{\theNX}
% ~~~ preserving the y-data ~~~~~~~~~~~~
\pgfkeyssetvalue{/data point/y}{#2}
% ~~~ original x-data, to be treated as labels ~~~~
\pgfkeyssetvalue{/data point/mylabel}{#1}
% ~~~ storing NX, y and (?) mylabel ~~~~~
\pgfdatapoint
}
{}{}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
\begin{tikzpicture}
\datavisualization [
scientific axes=clean,
x axis={label=X,
ticks={label=mylabel} % can't put date as labels
}, % rather it likes a list ?from data section?
y axis={label=birds},
all axes=grid,
][
visualize as line,
] data [format=ordinalX] {
% date,birds % skipping header
30/10/2023,1200
02/10/2023,1229
06/11/2023,980
09/11/2023,570
13/11/2023,308
16/11/2023,2590
20/11/2023,11700
}
% TEST / Bypass ?
% ~~~ if I had access to, say, /data point/mylabel here ...
% I might be able to iterate and place date as labels
info{
\foreach \x in {1,2,...,7}
\node[rotate=90,anchor=east,teal]
at (visualization cs: x={\x},y={-2e3}) {X-label};
}
;
\end{tikzpicture}
\end{document}
Respuesta1
Encontré una solución usando y adaptandoLa solución de Jake de 2013.. Puntos clave:
- la mayoría de las cosas suceden en la declaración
x axis={..., ticks={...
- llama un
typesetter
styles the nodes
para las etiquetas (rotar, etc. )- el tipógrafo se basa en a
global TeX list
, que funciona como una matriz - dentro del formato declarado
ordinalX
aappends
dicha lista - Yo uso a
LaTeX counter
en lugar depredefined TeX \@tempcnta
,ver aquí en StackExchange \makeatletter
y\makeatother
están incluidos, pero no parecen tener efecto, probablemente debido al diferente contador utilizado
\documentclass[10pt,border=3mm,tikz]{standalone}
\usetikzlibrary{datavisualization}
\newcounter{NX} % <<< using LaTeX counter istead of \@tempcnta
\makeatletter
% ~~~ introducing ordinal values for x ~~~~~~~~~
% converts (date,birds) into (NX,birds) in (x,y) world
\pgfdeclaredataformat{ordinalX}%
{} % No catcode changes
{\xdef\label@list{}}% initialise a global label list
{#1,#2}% data format
{%
\pgfmathaddtocounter{NX}{1}% advance
\pgfkeyssetvalue{/data point/x}{\theNX}%store counters result as x-data
\pgfkeyssetvalue{/data point/y}{#2}% the y-data (birds)
\xdef\label@list{\label@list,"#1"}% append label to list
\pgfdatapoint
}%
{}{}
% ~~~ typesetting the x-axis: putting labels instead of 1,2,3, ... ~~~~~~~~
\def\ticksfromlabellist#1{%
\pgfmathparse{{\label@list}[#1]}% retrieve label one by one
\pgfmathresult% result: text, i.e. 30/10/2023
}
\makeatother
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
\begin{tikzpicture}
\datavisualization [
scientific axes=clean,
x axis={
label=Date,
ticks={ % NEW
step=1,
tick typesetter/.code=\ticksfromlabellist{##1}, % typesetting labels, replacing 1,2,3,...
% style={text height=1ex}, % for proper vertical alignment
node style={rotate=90,anchor=east,teal}, % rotating etc.
}
},
y axis={label=birds},
all axes=grid,
][
visualize as line,
] data [format=ordinalX] {
% date,birds % skipping header
30/10/2023,1200
02/10/2023,1229
06/11/2023,980
09/11/2023,570
13/11/2023,308
16/11/2023,2590
20/11/2023,11700
};
\end{tikzpicture}
\end{document}