我正在尝试将条形图和折线图合并为一个图形。我绘制了 5 种不同材料的质量,它们具有 3 种不同的厚度。现在,我还有所有 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
这是原理证明。我并没有真正修复重叠的条形,因为我真的不知道你想要什么输出。但是,如果你在代码中修复了这个问题,就可以使用此解决方案。我绝对不是说这是最优雅的解决方案。