.png)
나는 를 사용하여 기후 그래프(기후 도표)를 만들고 싶지만 pgfplots
이 그래프에는 축 크기 조정에 대한 몇 가지 특별한 규칙(약 50년 전에 Walter와 Lieth가 정의함)이 있는데 를 사용하여 실현하는 방법을 전혀 모릅니다. pgfplots
왜냐하면 두 번째 y축은 스케일링은 사이에서 변경될 수 있으며 두 y축의 스케일링은 서로 결합됩니다. 아래 예.
규칙: 왼쪽 y축(온도 T)은 영하의 온도가 없으면 영점에서 시작하여 10°C 단위로 확장되고, 그렇지 않으면 영하 10°C 단위로 확장됩니다. 이것은 여전히 쉬운 부분이고(할 수 있습니다) 이제 어려운 부분입니다. 오른쪽 y축(비의 양)은 최대 300mm까지 T 값의 두 배로 확장됩니다. 그러나 300mm 이상의 비가 오면 100mm부터 시작하여 200mm 단위로 크기가 조정됩니다. 오른쪽 축은 절대 0 아래로 내려가지 않습니다.
내 질문은: 입력 값에 따라 축 크기 조정을 동적으로 변경하고 축을 서로 연결하는 데 사용해야 하는 명령은 무엇입니까? {x,y}{min,max}
, tick
그리고 친구만으로는 충분하지 않습니다. 나는 pgfplots를 사용하여 플롯을 그리는 기본 사항을 알고 있지만 이러한 동적 스케일링 접근 방식을 어디서 시작해야 하는지, 이 중 얼마나 많은 부분을 자체 코드로 계산해야 하는지, 얼마나 많은 pgfplots
작업을 수행할 수 있는지 전혀 모릅니다 . 예를 들어, 최대값을 찾기 위해 어떻게든 입력 데이터를 구문 분석해야 했지만 pgfplots
.
작업할 내용을 갖기 위해 첫 번째 예의 데이터는 다음과 같습니다.
#bombay.txt
#M T/°C N/mm
1 23.9 3
2 23.9 3
3 26.1 3
4 28.1 2
5 29.7 18
6 28.9 485
7 27.2 617
8 27.0 340
9 27.0 264
10 28.1 64
11 27.2 13
12 25.6 3
그리고 이것이 코드 방식으로 얻은 방법이지만 지금은 어떻게 진행해야 할지 모르겠습니다(색상, 선 스타일, 그리드 등은 지금은 중요하지 않습니다. 혼자서 할 수 있습니다. 축 스케일링/커플링이 문제입니다):
\documentclass{standalone}
\usepackage{pgfplots} \pgfplotsset{compat=newest}
\usepackage{siunitx}
\begin{document}
\begin{tikzpicture}
\def\filename{bombay.txt}
\def\monthnames{{"J","F","Mar","A","May","Jun","Jul","A","S","O","N","D"}}
\begin{axis}[
ylabel={Temperature in \si{\celsius}},
tick pos=left,
xticklabel={\pgfmathparse{\monthnames[Mod(\tick-1,12)]}\pgfmathresult},
xmin=1, xmax=12,
ymin=0, ytick={0,10,20,30,40,50}]
\addplot+[red, mark=none] table [x index=0, y index=1] {\filename};
\end{axis}
\begin{axis}[
ylabel={Rain in \si{\milli\metre}},
axis y line*=right,
hide x axis,
xmin=1, xmax=12, ymin=0]
\addplot+[blue, mark=none] table [x index=0, y index=2] {\filename};
\end{axis}
\end{tikzpicture}
\end{document}
예 1: 비 축의 스케일링 변경(> 300mm 때문에), T > 0만
예 2: 비 축은 항상 < 300mm이기 때문에 스케일링을 변경하지 않습니다. T < 0.
답변1
필요한 것은 스타일 설정으로 가능합니다.
- 비 축에 대한 비선형 변환을 구성합니다.
- 두 y축에 대해 적합한(결합된) 축 제한을 계산합니다.
- 두 y축 모두에 적합한(결합된) 단위를 계산합니다.
- 두 축의 시작/끝 위치를 결정하려면 수동 입력이 필요합니다. 귀하의 사용 사례에서 제가 이해한 바에 따르면 이 입력은 최소 온도와 최대 강수량으로 구성됩니다(다른 한도는 항상 암시적으로 바인딩됩니다).
나는 다음과 같은 고급 프로토타입에 도달했습니다.
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
% The following \pgfplotsset macro defines a *manual* wheather
% visualization system which couples temperature and rain axis.
\pgfplotsset{
rain trafo/.style={
y coord trafo/.code={%
\pgfmathparse{##1 > 100 ? 100 + 0.1*(##1 - 100) : ##1}%
},%
y coord inv trafo/.code={%
\pgfmathparse{##1 > 100 ? 100 + 10*(##1 - 100) : ##1}%
},%
%
% configure the allowed tick positions for the rain
% (UNTRANSFORMED!):
ytick={0,20,...,100,300,500,...,1000},
},
%
/wheather/temp min/.initial=,
/wheather/rain max/.initial=,
%
% USAGE: \pgfkeys{/wheather/set up={temp min=<min temperature>, rain max=<max rain axis value>}
% It will set up two styles "temp axis" and "rain axis". These
% styles will contain suitable axis limits and unit scales.
/wheather/set up/.code={%
\pgfkeysalso{/wheather/.cd,#1}%
%
% these values are supposed to be given:
\pgfkeysgetvalue{/wheather/rain max}\rainMax
\pgfkeysgetvalue{/wheather/temp min}\temperatureMin
%
% make sure they are given!
\ifx\rainMax\empty
\PackageError{wheather}{Please provide 'rain max=MAX RAIN VALUE IN AXIS'}{}%
\fi
\ifx\temperatureMin\empty
\PackageError{wheather}{Please provide 'temp min=MIN TEMPERATURE VALUE IN AXIS'}{}%
\fi
%
% now, compute the MISSING values. These are rain min and
% temperature max....
\begingroup
% do this in a group such that 'rain trafo' is only applied
% within the group...
%
% store it - just in case 'y coord trafo' is empty.
\let\pgfmathresult=\rainMax
%
\pgfplotsset{rain trafo,y coord trafo={\rainMax}}%
\global\let\rainMaxTransformed=\pgfmathresult
\pgfmathparse{\pgfmathresult /2}%
\global\let\temperatureMax=\pgfmathresult
\endgroup
%
\pgfmathparse{2*(\pgfkeysvalueof{/wheather/temp min})}%
\let\rainMin=\pgfmathresult
%
% now we want to compute a suitable axis scale for both axes.
% To this end, we scale them such that they fit into the value
% of \axisdefaultheight :
\pgfmathparse{\axisdefaultheight/(\temperatureMax-\temperatureMin)}%
\let\temperatureUnit=\pgfmathresult
%
\pgfmathparse{\axisdefaultheight/(\rainMaxTransformed-\rainMin)}%
\let\rainUnit=\pgfmathresult
%
% OK, compute the result:
\pgfplotsset{%
set layers,
%
% this is to be used for the temperature axis:
temp axis/.style={
y=\temperatureUnit,
ymin=\temperatureMin,
ymax=\temperatureMax,
%
% configure the allowed tick positions for a temperature:
ytick={-40,-30,-20,...,140},
% ... but only show the *label* for "small"
% temperatures:
yticklabel={%
\ifdim\tick pt<45pt
\pgfmathprintnumber\tick
\fi
},
ylabel={Temperature},
%tick pos=left,% seems to fail for 'axis x line=middle'!?
%
% configure the x axis:
axis x line*=middle,
xmin=1, xmax=12,
xtick={1,2,...,12},
xticklabels={J,F,M,A,M,J,J,A,S,O,N,D},
x tick label as interval,
grid=major,
},
%
% ... and this is to be used for the rain axis:
rain axis/.style={
y=\rainUnit,
ymin=\rainMin,
ymax=\rainMax,
% this range will be overwritten by 'rain trafo' if it
% is active:
ytick={0,20,...,400},
rain trafo,
yticklabel style={/pgf/number format/precision=0},
ylabel={Rain},
axis y line*=right,
hide x axis,
xmin=1, xmax=12,
},
}%
},
}
\begin{filecontents}{bombay.txt}
#bombay.txt
#M T/°C N/mm
1 23.9 3
2 23.9 3
3 26.1 3
4 28.1 2
5 29.7 18
6 28.9 485
7 27.2 617
8 27.0 340
9 27.0 264
10 28.1 64
11 27.2 13
12 25.6 3
\end{filecontents}
\begin{filecontents}{moskow.txt}
#M T/°C N/mm
1 -10.9 30
2 -12.9 23
3 -6.1 30
4 3.1 40
5 6.7 50
6 15.9 60
7 20.2 61
8 22.0 50
9 17.0 45
10 10.1 20
11 3.2 22
12 -9.6 25
\end{filecontents}
\begin{document}
\begin{tikzpicture}
\pgfplotsset{/wheather/set up={temp min=0, rain max=800}}
\def\filename{bombay.txt}
\begin{axis}[
temp axis,
]
\addplot+[red, mark=none] table [x index=0, y index=1] {\filename};
\end{axis}
\begin{axis}[
rain axis,
]
\addplot+[blue, mark=none] table [x index=0, y index=2] {\filename};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\pgfplotsset{
*clear* the nonlinear rain trafo. We do not want it here:
rain trafo/.style=,
/wheather/set up={temp min=-20, rain max=160},
}
\def\filename{moskow.txt}
\begin{axis}[
temp axis,
]
\addplot+[red, mark=none] table [x index=0, y index=1] {\filename};
\end{axis}
\begin{axis}[
rain axis,
]
\addplot+[blue, mark=none] table [x index=0, y index=2] {\filename};
\end{axis}
\end{tikzpicture}
\end{document}
나는 그것이 몇 가지 항목(주로 서식 지정 및 채우기 경로)이 남아 있지만 이미 꽤 좋다고 생각합니다.
그리고 pgfplots에는 실제로 "누락된 기능"인 미해결 문제가 하나 있습니다. 작성하자마자 axis x line=middle
pgfplots는 첫 번째 및 마지막 틱 레이블을 표시하지 않습니다. 이 응용 프로그램에는 매우 불행합니다. 나는 그것을 pgfplots의 할일 목록에 포함시킬 것입니다. 이 문제를 해결하려면 실행을 취소해야 할 수도 있습니다 axis x line=middle
. x 틱을 간격으로 표시한다는 것은 n 틱 위치에 대해 n-1 틱 레이블이 있다는 것을 의미합니다. 즉, 어떻게든 1월의 데이터 포인트를 복제해야 할 수도 있습니다.