我正在嘗試將條形圖和折線圖合併成一個圖形。我繪製了 3 種不同厚度的 5 種不同材料的品質。現在,我還有所有 15 個柱子的溫度數據。對於每種材料,我想將三個溫度數據點連接在一條線上,最好是傾斜的。如何將每個溫度值連接到對應的長條圖?
這是我到目前為止所得到的。 (對於材料 3 和 4,我只有一個溫度值,因此“僅標記”選項是可以的。)
\documentclass{article}
\usepackage{pgfplots}
\usepackage{anysize}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{figure}[!ht]
\centering
\pgfplotsset{width=14.5cm,
symbolic x coords={material1,material2,material3,material4,material5},
}
\begin{tikzpicture}
\begin{axis}
[
ybar=11pt,
axis x line*=bottom,
axis y line*=left,
ymin=0,ymax=1500,
ylabel=material mass $\mathrm{[kg]}$,
enlarge y limits=0.0,
enlarge x limits=0.15,
legend style={at={(1,-0.1)},draw=none},
legend columns=3,
x tick label style={text width=2.9cm,align=center},
xtick={data},
xtick align=inside,
minor y tick num=1,
height=0.37\linewidth,
bar width=0.5cm,
]
\addplot
[fill=black!30,draw=none]
coordinates{
(material1, 316.91)
(material2,338.93)
(material3,542.05)
(material4,653.4)
(material5,244.72)
};
\addplot
[fill=black!60,draw=none]
coordinates{
(material1,475.05)
(material2,508.06)
(material3,812.13 )
(material4,979.44)
(material5,366.83 )
};
\addplot
[fill=black!80,draw=none]
coordinates{
(material1,623.97)
(material2,676.96)
(material3,1084.65)
(material4,1305.05)
(material5,488.78)
};
\end{axis}
\begin{axis}
[
ymin=0,ymax=600,
axis y line*=right,
ylabel=temperature $\mathrm{[K]}$,
enlarge y limits=0.0,
enlarge x limits=0.15,
height=0.37\linewidth,
xticklabels=\empty
]
\addplot[very thick,draw=red!90]
coordinates{
(material1, 387.04)
(material1,274.51)
(material1,211.07)
};
\addplot[mark=circle,very thick,draw=red!90]
coordinates{
(material2,461.93)
(material2,326.88)
(material2,253.97)
};
\addplot[only marks,very thick,draw=red!90]
coordinates{
(material3,530.84)};
\addplot[only marks,very thick,draw=red!90]
coordinates{
(material4,484.68)};
\addplot[mark=circle,very thick,draw=red!90]
coordinates{
(material5,515.55)
(material5,350.43)
(material5,268.02)
};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
答案1
您會得到垂直線,因為當您不使用時,ybar
座標不會改變。所以技巧是ybar
在第二個axis
環境中也使用。但因為您不想看到/顯示它們,所以我們使它們不可見,並透過濫用該nodes near coords
功能來儲存座標。有了它們,就可以輕鬆地分別繪製線條和標記。
具體請看程式碼中的註解。
(請注意,我允許自己大幅簡化您的程式碼。我希望您同意這更具可讀性,因此更易於維護。)
% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{
compat=1.16,
% create a custom style to store common `axis options`
my axis style/.style={
width=\linewidth,
height=0.37\linewidth,
ybar=5pt, % <-- reduced so the bars don't overlap
bar width=0.5cm,
enlarge y limits=0.0,
enlarge x limits=0.15,
% to avoid to repeat the symbolic coords over and over again,
% use them from a table ...
xticklabels from table={\data}{material},
% ... ensure that every data points get a corresponding xtick ...
xtick={data},
% ... and then just number the entries by the row index of the table
table/x expr={\coordindex},
xtick align=inside,
minor y tick num=1,
},
% create a style to store the coordinates of the
% temperature data
Name/.style={
% use the `nodes near coords` for that
nodes near coords,
nodes near coords style={
% they shouldn't show any value ...
coordinate,
% but store coordinate labels which can later be used
name=#1\coordindex,
},
},
}
% create a table of data
% (which is much more clearly arranged than the "coordinates")
% use any number that can clearly be distinguished from regular values to indicate
% that you don't have any data here. In this case, I used -1.
% (You can't use NaN here, because then no coordinate will be created and thus
% the (automatic) numbering of the named coordinates is working as expected.)
\pgfplotstableread{
material d1 d2 d3 T1 T2 T3
material1 316.91 475.05 623.97 387.04 274.51 211.07
material2 338.93 508.06 676.96 461.93 326.88 253.97
material3 542.05 812.13 1084.65 -1 530.84 -1
material4 653.40 979.44 1305.05 -1 484.68 -1
material5 244.72 366.83 488.78 515.55 350.43 268.02
}{\data}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
% call the created style
my axis style,
% (list the remaining options)
ymin=0,
ymax=1500,
axis x line*=bottom,
axis y line*=left,
ylabel=material mass $\mathrm{[kg]}$,
% use a (custom) `cycle list` which is also much clearer than
% providing the options to each `\addplot` command
cycle list={
{draw=none,fill=black!30},
{draw=none,fill=black!60},
{draw=none,fill=black!80},
},
]
% then this here is very simple
% (and should be self-explanatory)
\addplot table [y=d1] {\data};
\addplot table [y=d2] {\data};
\addplot table [y=d3] {\data};
\end{axis}
% here we also create a ybar plot, but don't draw the bars.
% Instead, we just store named coordinates at the bar ends.
\begin{axis}[
my axis style,
%
ymin=0,
ymax=600,
axis y line*=right,
ylabel=temperature $\mathrm{[K]}$,
xticklabels=\empty,
% make the bars invisible
only marks,
]
% use the custom `Name` style here to store the named coordinates
\addplot [Name=a] table [y=T1] {\data};
\addplot [Name=b] table [y=T2] {\data};
\addplot [Name=c] table [y=T3] {\data};
\end{axis}
% the named coordinates can only be accessed after the `axis` environment.
% Now simply draw the lines ...
\foreach \i in {0,1,4} {
\draw [very thick,red!90] (a\i) -- (b\i) -- (c\i);
}
% ... and marks
\foreach \i in {2,3} {
\fill [red!90] (b\i) circle [radius=2.5pt];
}
\end{tikzpicture}
\end{document}
答案2
我必須重置您的設置的一些值才能獲得半合理的輸出並且沒有警告。訪問條的垂直位置的一種可能方法是使用nodes near coords
自動命名這個答案。這允許人們重建繪圖。
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{figure}[!ht]
\centering
\pgfplotsset{width=0.8\linewidth,
symbolic x coords={material1,material2,material3,material4,material5},
}
\pgfplotsset{% https://tex.stackexchange.com/a/75811/121799
name nodes near coords/.style={nodes near coords={},
every node near coord/.append style={anchor=center,coordinate,
name=#1-\coordindex,%/utils/exec=\typeout{#1-\coordindex},
alias=#1-last,
},
},
name nodes near coords/.default=coordnode
}
\begin{tikzpicture}
\begin{axis}
[
ybar=11pt,
axis x line*=bottom,
axis y line*=left,
ymin=0,ymax=1500,
ylabel=material mass $\mathrm{[kg]}$,
enlarge y limits=0.0,
enlarge x limits=0.15,
legend style={at={(1,-0.1)},draw=none},
legend columns=3,
x tick label style={text width=2.9cm,align=center},
xtick={data},
xtick align=inside,
minor y tick num=1,
height=0.37\linewidth,
bar width=0.3cm,
]
\addplot
[fill=black!30,draw=none,name nodes near coords=m1]
coordinates{
(material1, 316.91)
(material2,338.93)
(material3,542.05)
(material4,653.4)
(material5,244.72)
};
\addplot
[fill=black!60,draw=none,name nodes near coords=m2]
coordinates{
(material1,475.05)
(material2,508.06)
(material3,812.13 )
(material4,979.44)
(material5,366.83 )
};
\addplot
[fill=black!80,draw=none,name nodes near coords=m3]
coordinates{
(material1,623.97)
(material2,676.96)
(material3,1084.65)
(material4,1305.05)
(material5,488.78)
};
\end{axis}
\begin{axis}
[
ymin=0,ymax=600,
axis y line*=right,
ylabel=temperature $\mathrm{[K]}$,
enlarge y limits=0.0,
enlarge x limits=0.15,
height=0.37\linewidth,
xticklabels=\empty
]
\addplot[very thick,draw=red!90,opacity=0,name nodes near coords=n1]
coordinates{
(material1, 387.04)
(material1,274.51)
(material1,211.07)
};
\addplot[mark=circle,very thick,draw=red!90,opacity=0,name nodes near coords=n2]
coordinates{
(material2,461.93)
(material2,326.88)
(material2,253.97)
};
\addplot[only marks,very thick,draw=red!90]
coordinates{
(material3,530.84)};
\addplot[only marks,very thick,draw=red!90]
coordinates{
(material4,484.68)};
\addplot[mark=circle,very thick,draw=red!90,opacity=0,name nodes near coords=n5]
coordinates{
(material5,515.55)
(material5,350.43)
(material5,268.02)
};
\end{axis}
\draw[very thick,draw=red!90] plot[samples at={0,1,2}]
(m\the\numexpr\x+1\relax-0|-n1-\x);
\draw[mark=*,very thick,draw=red!90]
plot[samples at={0,1,2}] (m\the\numexpr\x+1\relax-1|-n2-\x);
\draw[mark=*,very thick,draw=red!90]
plot[samples at={0,1,2}] (m\the\numexpr\x+1\relax-4|-n5-\x);
\end{tikzpicture}
\end{figure}
\end{document}2
這是原則性的證明。我並沒有真正修復重疊的條形,因為我真的不知道你想要什麼輸出。但是,如果您在程式碼中修復了此問題,則可以使用此解決方案。我絕對不是說這是最優雅的解決方案。