背景
假設您在 的數據部分中有這樣的數據datavisualization
,這些數據也可能來自文件,
date,birds
30/10/2023,1200
02/10/2023,1229
...
或者
species,birds
spec4,1200
spec1,1229
...
\datavisualization
提供兩種視覺化效果scientific axes
和school book axes
,兩者都需要 xy 資料。
問題
用計數器取代文字 x 資料並引入簡單的序數標度並不是什麼大問題。但是如何保留或存取原始 x 資料並將它們作為標籤放在 x 軸上而不是 1,2,... ?
嘗試
下面的程式碼提供了\pgfdeclaredataformat{ordinalX}
,它用一個簡單的計數器 NX 取代了 x-data。
我知道我可以將清單(例如 via ticks={major at={1 as spec4,...}}
)手動寫入 x 軸語句中。但在處理數據時,這不是一個好主意,數據部分已經給了。
看起來我不知道這裡使用的資料範圍、存取權限、資料結構,甚至不知道僅從 pgfmanual wrt 中猜測正確的 pgfkey datavisualization
。
這只能透過引入全域變數(例如 pgfkeys、l3、「陣列」、資料物件等)來解決嗎?如果是這樣,聲明的格式會將提取的原始 x 資料放在那裡嗎?
\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}
答案1
我找到了一個使用和適應的解決方案傑克 2013 年的解決方案。關鍵點:
- 大多數事情發生在聲明中
x axis={..., ticks={...
- 它調用一個
typesetter
- 用於
styles the nodes
標籤(旋轉等) - 排字機依賴 a
global TeX list
,其功能類似於數組 - 在聲明的格式內
ordinalX
它appends
到所述列表 - 我用 a
LaTeX counter
代替predefined TeX \@tempcnta
,請參閱 StackExchange 上的此處 \makeatletter
和\makeatother
被包括在內,但似乎沒有產生效果,可能是由於使用了不同的計數器
\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}