Como combino um gráfico de barras e um gráfico de linhas com pgfplots/tikz?

Como combino um gráfico de barras e um gráfico de linhas com pgfplots/tikz?

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.)

gráfico de barras e linhas

\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 ybarnão há mudança de coordenadas. Então o truque é usar também ybarno segundo axisambiente. 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 coordsrecurso. 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}

imagem mostrando o resultado do código acima

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

insira a descrição da imagem aqui

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.

informação relacionada