Я пытаюсь объединить столбчатую диаграмму и линейную диаграмму в один рисунок. Я нанес массу 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
Это доказательство принципа. Я на самом деле не исправил перекрывающиеся полосы, потому что понятия не имею, какой вывод вам нужен. Однако, если вы исправите это в своем коде, это решение можно использовать. Я определенно не говорю, что это самое элегантное решение из возможных.