Estou tentando combinar um gráfico de barras e um gráfico de linhas em uma figura. Plotei a massa de 5 materiais diferentes para 3 espessuras diferentes. Agora também tenho dados de temperatura para todas as 15 barras. Para cada material, quero conectar os três pontos de dados de temperatura em uma linha, de preferência inclinada. Como conecto cada valor de temperatura à respectiva barra?
Isso é o que consegui até agora. (para os materiais 3 e 4, tenho apenas um valor de temperatura, então a opção "apenas marcas" está correta.)
\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}
Responder1
Você obtém as linhas verticais, porque quando não usa ybar
não há mudança de coordenadas. Então o truque é usar também ybar
no segundo axis
ambiente. Mas como você não quer vê-los/mostrá-los, nós os tornamos invisíveis e apenas armazenamos as coordenadas através do uso indevido do nodes near coords
recurso. Com eles fica simples desenhar as linhas e marcas, respectivamente.
Para obter detalhes, dê uma olhada nos comentários no código.
(Observe que me permiti simplificar bastante o seu código. Espero que você concorde que isso é muito mais legível e, portanto, fácil de manter.)
% 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}
Responder2
Tive que redefinir alguns valores de suas configurações para obter uma saída semi-razoável e sem avisos. Uma forma possível de obter acesso às posições verticais das barras é utilizarnodes near coords
com a nomeação automática deesta resposta. Isso permite reconstruir as parcelas.
\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
Esta é uma prova de princípio. Eu realmente não consertei as barras sobrepostas porque realmente não tenho ideia de qual resultado você está procurando. No entanto, se você corrigir isso em seu código, esta solução poderá ser usada. Definitivamente, não estou dizendo que esta seja a solução mais elegante possível.