legenda de linha para gráficos de malha

legenda de linha para gráficos de malha

Estou fazendo um gráfico de grupo de curvas relacionadas. Como eles estão relacionados por um parâmetro, quero colori-los de acordo com (uma função) desse parâmetro. Para isso usei a opção mesh e depois usei point meta para indicar a cor que deveria ter. No entanto, a legenda é uma grade de malha e quero que seja uma linha colorida. Qual é a maneira mais limpa de fazer isso?

Encontrei a postagem relacionadaLegenda com marcadores para gráfico de malhamas não consegui adaptá-lo ao meu caso.

 \begin{tikzpicture}
    \begin{groupplot}[group style={group size={2 by 1},
                      xlabels at=edge bottom,
                      xticklabels at=edge bottom},
                    axis lines=left, domain=-5:5,
                    xlabel=$x$,
                    width=0.5\textwidth,colormap/hot,
                    legend columns=-1,
                    legend entries={ $\beta=0.1$, $\beta=0.5$,
                    $\beta=0.8$, $\beta=1.0$, $\beta=2.0$, $\beta=5.0$},
                    legend to name={fig:mm_temp_legend}]
                    ]
      \nextgroupplot[ylabel={$p(x)$}]
      \pgfplotsforeachungrouped \be/\zedd in {
                0.1/12.4595,
                0.5/18.3263,
                0.8/29.6888,
                1.0/43.0372,
                2.0/403.539,
                5.0/1.07923e6 } {
        \addplot+[line legend,samples=200,no marks,solid,mesh,point meta={ln(\be)}]
        gnuplot {exp(\be*(0.4*(x-0.3)**2-0.02*x**4))/\zedd};
      }
      %
      \nextgroupplot[ylabel={$-\log p(x)$},ymin=0]
      \pgfplotsforeachungrouped \be/\zedd in {
                0.1/12.4595,
                0.5/18.3263,
                0.8/29.6888,
                1.0/43.0372,
                2.0/403.539,
                5.0/1.07923e6 } {
        \addplot+[samples=200,no marks,solid,mesh,point meta={ln(\be)}]
        gnuplot {\be*(-0.4*(x-0.3)**2+0.02*x**4)+log(\zedd)};
      }
    \end{groupplot}
  \end{tikzpicture}

aqui está como parece

Responder1

O que você está tentando alcançar é possível. No entanto, na verdade é mais uma solicitação de recurso (o que explica por que apresenta dificuldades).

O problema surge porque uma lenda nãonãotem os mesmos valores de dados de cores (também conhecidos como "meta de ponto") que seu gráfico associado. E do meu ponto de vista, isso é realmente o que se espera. No seu exemplo, você usou point metapara definir uma cor e vejo que é útil para você. No entanto, a legenda não pode saber a cor resultante.

A falta de mapeamento de cores em uma legenda é um problema inerente à abordagem aqui. Porém, você pode colocar line legendafter meshpara gerar uma legenda de linha (com a cor errada pelo motivo explicado acima).

Observe que seu exemplo realmente geradoislegendas porque as opções depois \begin{groupplot}se aplicam aamboseixos seguintes.

Dito isto, é possível atender à sua solicitação de recurso com uma chamada de API relativamente simples. Como o pgfplots vem sem uma API pública de nível básico, este comando não está documentado. Ele mapeia um valor escalar em algum mapa de cores.

A ideia é definir uma cor para cada valor possível deln(\be) antecipadamentee para usar essas cores predefinidas posteriormente:

\documentclass{article}

\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\usepgfplotslibrary{groupplots}


\begin{document}
\thispagestyle{empty}

\pgfplotsset{
    colormap/hot,
}%
\pgfmathparse{ln(0.1)}%
\let\BEMIN=\pgfmathresult

\pgfmathparse{ln(5)}%
\let\BEMAX=\pgfmathresult

% FIRST: define one color for every value of \be :
\pgfplotsforeachungrouped \be in {
        0.1,
        0.5,
        0.8,
        1.0,
        2.0,
        5.0} {
    \pgfmathparse{ln(\be)}
    \let\value=\pgfmathresult
    %
    \pgfplotscolormapaccess
            [\BEMIN:\BEMAX]% IMPORTANT for the mapping.
            {\value}
            {\pgfkeysvalueof{/pgfplots/colormap name}}
    % now, \pgfmathresult contains {<R>,<G>,<B>}
    % 
    \edef\temp{\noexpand\definecolor{be color \be}{rgb}{\pgfmathresult}}%
    %
    % now, \temp contains '\definecolor{be color 0.1}{rgb}{<R>,<G>,<B>}'
    \temp
}

\begin{tikzpicture}
    \begin{groupplot}[group style={group size={2 by 1},
                      xlabels at=edge bottom,
                      xticklabels at=edge bottom},
                    axis lines=left, domain=-5:5,
                    xlabel=$x$,
                    width=0.5\textwidth,%colormap/hot,
                    legend columns=-1,
                    ]
                    ]
      \nextgroupplot[ylabel={$p(x)$},
        % HINT: I added 'legend entries here as opposed to the environment:
        % only ONE sub-plot should have legend, not both
        legend entries={ $\beta=0.1$, $\beta=0.5$,
            $\beta=0.8$, $\beta=1.0$, $\beta=2.0$, $\beta=5.0$},
        legend to name={fig:mm_temp_legend},
    ]

      \pgfplotsforeachungrouped \be/\zedd in {
                0.1/12.4595,
                0.5/18.3263,
                0.8/29.6888,
                1.0/43.0372,
                2.0/403.539,
                5.0/1.07923e6 } {
        % NOTE: I replaced 'no marks' by 'mark=none'. Seems as if 'no
        % marks' does not make it into the legend (!?)
        %
        % this \edef\temp is required to expand 'draw=be color \be' to
        % 'draw=be color 0.1' etc:
        \edef\temp{%
            \noexpand\addplot+[draw=be color \be,id=\be,samples=200,mark=none,solid,]
                gnuplot {exp(\be*(0.4*(x-0.3)**2-0.02*x**4))/\zedd};
        }%
        \temp
      }
      %
      \nextgroupplot[ylabel={$-\log p(x)$},ymin=0]
      \pgfplotsforeachungrouped \be/\zedd in {
                0.1/12.4595,
                0.5/18.3263,
                0.8/29.6888,
                1.0/43.0372,
                2.0/403.539,
                5.0/1.07923e6 } {
        \addplot+[id=2_\be,samples=200,no marks,solid,mesh,point meta={ln(\be)}]
        gnuplot {\be*(-0.4*(x-0.3)**2+0.02*x**4)+log(\zedd)};
      }
    \end{groupplot}
  \end{tikzpicture}

  \ref{fig:mm_temp_legend}
\end{document}

insira a descrição da imagem aqui

Um passo importante é calcular o limite inferior e superior dos ln(\be)valores, caso contrário o mapeamento será impossível. O loop real envolve um pouco de controle básico de expansão; compararPor onde começo a programação LaTeX?para detalhes.

O \addplot+comando também precisa ser ampliado; caso contrário, o \bevalor seria perdido. Isso ocorre porque draw=...é avaliado na “fase de visualização” em que é iniciada \end{groupplot}(não antes). E draw=...lembraria apenas do valor não expandido que depende de \be.

Mantive o segundo gráfico intacto para permitir uma comparação simples. Você pode adotá-lo se esta resposta atender às suas necessidades.

Observe que adicionei id=...para evitar chamadas repetidas ao gnuplot na minha máquina e que tive que substituir no markspor mark=none(este último parece ser um bug ou problema de usabilidade no pgfplots, eu cuidarei disso).

Veja também uma aplicação relacionada de pesquisas personalizadas no mapa de cores em Desenhando mapas de calor usando TikZ


Agora que implementei tudo isso; Inclinei-me para trás e percebi que poderia ter sido muito mais útil reimplementar seu caso de uso por meio de cycle lists. Essas listas mostram como o pgfplots normalmente lida com cores variadas; eles são simples de usar e totalmente suportados quando se trata de lendas. Se você acha que cycle listssão melhores (talvez você realmente queira um mapa de cores, então eles não são), você pode encontrar mais informações no manual do pgfplots.

informação relacionada