Producción:

Producción:

Tengo varias curvas/conjuntos de datos (obtenidos de simulaciones de Monte Carlo) con errores y dependientes de x que me gustaría trazar con los errores indicados de alguna manera. Dado que cada curva consta de una cantidad bastante grande de puntos de datos con errores bastante pequeños, el uso de barras de error ordinarias no parece ser la solución más informativa/estética. En cambio, creo que sería mejor indicar el error por el grosor de la línea (local) (o el grosor en la dirección y). Podría hacerse, por ejemplo, trazando y(x)+dy(x) e y(x)-dy(x) y rellenando entre las dos curvas. Pero, ¿cómo se hace eso (de una manera razonablemente fácil, recuerde: ¡tengo varias curvas!) en Pgfplots?

Mi pregunta tal vez sea algo similar aÉste, pero no sé cómo realizar las manipulaciones de la tabla (dentro de Pgfplots) necesarias en mi caso.

Aquí hay un ejemplo simplificado de cómo se ven mis archivos de datos:

x y dy
0 2 0.1
1 4 0.5
2 3 0.2
3 3 0.3

Respuesta1

Puede utilizar gráficos apilados para dibujar las bandas de incertidumbre antes de trazar la línea de datos real. Primero diría \addplot table [y expr=\thisrow{<data col>}-\thisrow{<error col}] {<datatable>};que se determine el límite inferior y luego \addplot [fill=<colour>] table [y expr=2*\thisrow{<error col}] {<datatable>} \closedcycle;que se llene el área entre el límite inferior y el superior.

Estos dos \addplotcomandos se pueden incluir en una macro para generar los gráficos, de la siguiente manera:

\newcommand{\errorband}[5][]{ % x column, y column, error column, optional argument for setting style of the area plot
\pgfplotstableread[col sep=comma, skip first n=2]{#2}\datatable
    % Lower bound (invisible plot)
    \addplot [draw=none, stack plots=y, forget plot] table [
        x={#3},
        y expr=\thisrow{#4}-\thisrow{#5}
    ] {\datatable};

    % Stack twice the error, draw as area plot
    \addplot [draw=none, fill=gray!40, stack plots=y, area legend, #1] table [
        x={#3},
        y expr=2*\thisrow{#5}
    ] {\datatable} \closedcycle;

    % Reset stack using invisible plot
    \addplot [forget plot, stack plots=y,draw=none] table [x={#3}, y expr=-(\thisrow{#4}+\thisrow{#5})] {\datatable};
}

puedes generar un gráfico con una banda de error usando

\errorband[<plot options>]{<data file>}{<x column>}{<y column>}{<error column>}

A continuación se muestra un ejemplo que traza elExtensión media del hielo marino del norte y del sur.

Fetterer, F., K. Knowles, W. Meier, M. Savoie y AK Windnagel. 2017, actualizado diariamente. Índice de hielo marino, versión 3. [Datos/Norte+Sur/Mes]. Boulder, Colorado, Estados Unidos. NSIDC: Centro Nacional de Datos sobre Hielo y Nieve. doi:https://doi.org/10.7265/N5K072F8.

\documentclass{article}
\usepackage{pgfplots, pgfplotstable}


\begin{document}

\newcommand{\errorband}[5][]{ % x column, y column, error column, optional argument for setting style of the area plot
\pgfplotstableread[col sep=comma, skip first n=2]{#2}\datatable
    % Lower bound (invisible plot)
    \addplot [draw=none, stack plots=y, forget plot] table [
        x={#3},
        y expr=\thisrow{#4}-2*\thisrow{#5}
    ] {\datatable};

    % Stack twice the error, draw as area plot
    \addplot [draw=none, fill=gray!40, stack plots=y, area legend, #1] table [
        x={#3},
        y expr=4*\thisrow{#5}
    ] {\datatable} \closedcycle;

    % Reset stack using invisible plot
    \addplot [forget plot, stack plots=y,draw=none] table [x={#3}, y expr=-(\thisrow{#4}+2*\thisrow{#5})] {\datatable};
}




\begin{tikzpicture}
\begin{axis}[
    compat=1.5.1,
    no markers,
    enlarge x limits=false,
    ymin=0,
    xlabel=Day of the Year,
    ylabel=Sea Ice Extent\quad/\quad $10^6\,\mathrm{km}^2$,
    legend entries={
        $\pm$ 2 Standard Deviation,
        NH 1997 to 2000 Average,
        $\pm$ 2 Standard Deviation,
        SH 1997 to 2000 Average,
        NH 2012,
        SH 2012
    },
    legend reversed,
    legend pos=outer north east,
    legend cell align=left,
    x post scale=1.2
]

% Northern Hemisphere Average
\errorband[orange, opacity=0.5]{NH_seaice_extent_climatology_1979-2000.csv}{0}{3}{4}

% Northern Hemisphere 2012
\addplot [thick, orange!50!black] table [
    x index=0,
    y index=3,
    skip first n=2,
    col sep=comma,
] {NH_seaice_extent_climatology_1979-2000.csv};

% Southern Hemisphere Average
\errorband[cyan, opacity=0.5]{SH_seaice_extent_climatology_1979-2000.csv}{0}{3}{4}


% Southern Hemisphere 2012
\addplot [thick, cyan!50!black] table [
    x index=0,
    y index=3,
    skip first n=2,
    col sep=comma,
] {SH_seaice_extent_climatology_1979-2000.csv};




\addplot [ultra thick,red] table [
    col sep=comma,
    skip first n=367,
    x expr=\coordindex,
    y index=3
] {NH_seaice_extent_nrt.csv};

\addplot [ultra thick,blue] table [
    col sep=comma,
    skip first n=367,
    x expr=\coordindex,
    y index=3
] {SH_seaice_extent_nrt.csv};
%

\end{axis}
\end{tikzpicture}


\end{document}

ACTUALIZAR

Los datos disponibles actualmente cubren la extensión promedio del hielo marino de 1981 a 2010. Para mayor reproducibilidad, el código LaTeX se puede actualizar de la siguiente manera (excluyendo los diagramas de líneas NH y SH 2012):

        $\pm$ 2 Standard Deviation,
        NH 1981 to 2010 Average,
        $\pm$ 2 Standard Deviation,
        SH 1981 to 2010 Average
    },
    legend reversed,
    legend pos=outer north east,
    legend cell align=left,
    x post scale=1.2
]

% Northern Hemisphere Average
\errorband[orange, opacity=0.5]{N_seaice_extent_climatology_1981-2010_v3.0.csv}{0}{1}{2}

% Northern Hemisphere 2012
\addplot [thick, orange!50!black] table [
    x index=0,
    y index=1,
    skip first n=2,
    col sep=comma,
] {fig/north.csv};

% Southern Hemisphere Average
% \errorband[<plot options>]{<data file>}{<x column>}{<y column>}{<error column>}
\errorband[cyan, opacity=0.5]{S_seaice_extent_climatology_1981-2010_v3.0.csv}{0}{1}{2}


% Southern Hemisphere 2012
\addplot [thick, cyan!50!black] table [
    x index=0,
    y index=1,
    skip first n=2,
    col sep=comma,
] {S_seaice_extent_climatology_1981-2010_v3.0.csv};

Respuesta2

Puede utilizar una meshgráfica con variables line width. Sin embargo, esto provoca transiciones irregulares de un segmento de línea al siguiente. Pero quizás sea factible:

ingrese la descripción de la imagen aquí

En caso de que tenga conjuntos de datos más pequeños, los marcadores pueden ocultar las transiciones:

ingrese la descripción de la imagen aquí

Aquí está el código:

\documentclass{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.5}

\begin{document}

\begin{tikzpicture}
% avoid false-positive compilation errors:
\def\pgfplotspointmetatransformed{1000}

    \begin{axis}[ymin=0,ymax=10]
    \addplot+[
        mesh,
        blue,
        %no marks,
        every mark/.append style={line width=1pt,mark size=4pt,fill=blue!80!black},
        shader=flat corner,
        line width=1pt+5pt*\pgfplotspointmetatransformed/1000
    ] 
    table[point meta=\thisrow{dy}] {
    x y dy
    0 2 0.1
    1 4 0.5
    2 3 0.2
    3 3 0.3
    };
    \end{axis}
\end{tikzpicture}
\end{document}

La idea clave es que (a) un meshgráfico dibuja segmentos de línea individuales y (b) \pgfplotspointmetatransformedcontiene los point metadatos de una manera completamente normalizada: la entrada de metadatos más pequeña (0,1 aquí) se obtiene \pgfplotspointmetatransformed=0y la más grande (0,5 aquí) se obtiene \pgfplotspointmetatransformed=1000. Los valores intermedios se interpolan linealmente. En consecuencia, podemos usarlos con seguridad line widthcomo se indicó anteriormente.

Tenga en cuenta que las opciones se evalúan en contextos donde esta metamacro de puntos no está disponible. Con este fin, lo definí como 1000 globalmente (lo que debería estar bien para estos contextos).

Respuesta3

He estado jugando con la fillbetweenbiblioteca últimamente y pensé que sería ideal para este escenario.

La respuesta está inspirada en la respuesta anterior de Jake, pero utiliza la fillbetweenbiblioteca introducida en pgfplotsla versión 1.10 en lugar de gráficos apilados.

Producción:

Producción


La errorbandmacro toma seis argumentos obligatorios: nombre de la tabla de datos, columna x, columna y, columna de error, color de línea y banda de error, y opacidad de la banda de error.

Funciona creando gráficos auxiliares invisibles para los límites superior e inferior del error y nombrándolos para que los utilice la fillbetweenbiblioteca. fillbetweenutiliza los argumentos de color y opacidad como configuración de la banda de error. Finalmente, traza la columna y encima de la banda de error usando el color proporcionado.

Los gráficos auxiliares y fillbetweenlos gráficos de bandas de error se olvidan por lo que no se incluyen en la leyenda. Esto hace que sea fácil de usar errorbandinmediatamente seguido \addlegendentry(o \legendal final) para generar una leyenda.

(Datos no mostrados.)

Solución:

\documentclass[x11names]{standalone}

\usepackage{pgfplots,pgfplotstable}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.10}

% Takes six arguments: data table name, x column, y column, error column,
% color and error bar opacity.
% ---
% Creates invisible plots for the upper and lower boundaries of the error,
% and names them. Then uses fill between to fill between the named upper and
% lower error boundaries. All these plots are forgotten so that they are not
% included in the legend. Finally, plots the y column above the error band.
\newcommand{\errorband}[6]{
\pgfplotstableread{#1}\datatable
  \addplot [name path=pluserror,draw=none,no markers,forget plot]
    table [x={#2},y expr=\thisrow{#3}+\thisrow{#4}] {\datatable};

  \addplot [name path=minuserror,draw=none,no markers,forget plot]
    table [x={#2},y expr=\thisrow{#3}-\thisrow{#4}] {\datatable};

  \addplot [forget plot,fill=#5,opacity=#6]
    fill between[on layer={},of=pluserror and minuserror];

  \addplot [#5,thick,no markers]
    table [x={#2},y={#3}] {\datatable};
}

\begin{document}
\begin{tikzpicture}%
  \begin{axis}[%
    width=10cm,
    height=10cm,
    scale only axis,
    xlabel={$x$},
    ylabel={$y$},
    enlarge x limits=false,
    grid=major,
    legend style={
      column sep=3pt,
      nodes={right},
      legend pos=south east,
    },
  ]

    \errorband{./data.dat}{0}{1}{2}{Firebrick2}{0.4}
    \addlegendentry{Data}

    \errorband{./data.dat}{0}{3}{4}{SpringGreen4}{0.4}
    \addlegendentry{More data}

  \end{axis}
\end{tikzpicture}%
\end{document}

Consideraciones de rendimiento:

Para aquellos que todavía leen, supongo que trazar las tramas invisibles sólo para nombrarlas hace que esto sea menos eficiente de lo que podría ser. Si alguien sabe una manera de reemplazar esto:

\addplot [name path=pluserror,draw=none,no markers,forget plot]
    table [x={#2},y expr=\thisrow{#3}+\thisrow{#4}] {\datatable};

con algo como:

\path[name path=pluserror] table [x={#2},y expr=\thisrow{#3}+\thisrow{#4}] {\datatable};

que sería genial. Supongo \pathque en realidad no pierde el tiempo dibujando, lo que lo haría más eficiente. No estoy seguro de cómo hacerlo o incluso si mejoraría la eficiencia.

información relacionada