Ausgabe:

Ausgabe:

Ich habe mehrere Kurven/Datensätze (aus Monte-Carlo-Simulationen) mit x-abhängigen y-Fehlern, die ich gerne mit irgendwie angegebener Fehlerdarstellung darstellen würde. Da jede Kurve aus einer ziemlich großen Anzahl von Datenpunkten mit relativ kleinen Fehlern besteht, scheint die Verwendung gewöhnlicher Fehlerbalken nicht die informativste/ästhetischste Lösung zu sein. Stattdessen fände ich es schöner, den Fehler durch (lokale) Linienstärke (oder Stärke in y-Richtung) anzuzeigen. Dies könnte beispielsweise durch Aufzeichnen von y(x)+dy(x) und y(x)-dy(x) und Ausfüllen der beiden Kurven erfolgen. Aber wie macht man das (auf einigermaßen einfache Weise – denken Sie daran: ich habe mehrere Kurven!) in Pgfplots?

Meine Frage ist vielleicht etwas ähnlich wieDieses hier, aber ich weiß nicht, wie ich die in meinem Fall erforderlichen Tabellenmanipulationen (innerhalb von Pgfplots) durchführen soll.

Hier ist ein vereinfachtes Beispiel, wie meine Datendateien aussehen:

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

Antwort1

Sie können gestapelte Diagramme verwenden, um die Unsicherheitsbänder zu zeichnen, bevor Sie die eigentliche Datenlinie zeichnen. Zuerst müssen Sie \addplot table [y expr=\thisrow{<data col>}-\thisrow{<error col}] {<datatable>};die Untergrenze bestimmen und dann \addplot [fill=<colour>] table [y expr=2*\thisrow{<error col}] {<datatable>} \closedcycle;den Bereich zwischen der Unter- und Obergrenze ausfüllen.

Diese beiden \addplotBefehle können in ein Makro eingebettet werden, um die Diagramme wie folgt zu generieren:

\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};
}

Sie können ein Diagramm mit einem Fehlerband erstellen mit

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

Unten sehen Sie ein Beispiel für die Darstellung derDurchschnittliche nördliche und südliche Meereisausdehnung.

Fetterer, F., K. Knowles, W. Meier, M. Savoie und AK Windnagel. 2017, täglich aktualisiert. Sea Ice Index, Version 3. [Daten/Nord+Süd/Monat]. Boulder, Colorado USA. NSIDC: National Snow and Ice Data Center. 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}

AKTUALISIEREN

Die derzeit verfügbaren Daten decken die durchschnittliche Ausdehnung des Meereises von 1981 bis 2010 ab. Zur Reproduzierbarkeit kann der LaTeX-Code wie folgt aktualisiert werden (ausgenommen die Liniendiagramme von NH und 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};

Antwort2

meshSie können ein Diagramm mit variierenden verwenden line width. Dies führt jedoch zu unsanften Übergängen von einem Liniensegment zum nächsten. Aber vielleicht ist es machbar:

Bildbeschreibung hier eingeben

Bei kleineren Datensätzen können Markierungen die Übergänge verbergen:

Bildbeschreibung hier eingeben

Hier ist der Code:

\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}

Die Schlüsselidee besteht darin, dass (a) ein meshDiagramm einzelne Liniensegmente zeichnet und (b) \pgfplotspointmetatransformeddie point metaDaten vollständig normalisiert enthält: Der kleinste Metadateneintrag (hier 0,1) erhält \pgfplotspointmetatransformed=0und der größte (hier 0,5) erhält \pgfplotspointmetatransformed=1000. Die Werte dazwischen werden linear interpoliert. Folglich können wir sie line widthwie oben beschrieben problemlos verwenden.

Beachten Sie, dass die Optionen in Kontexten ausgewertet werden, in denen dieses Punktmetamakro nicht verfügbar ist. Zu diesem Zweck habe ich es global als 1000 definiert (was für diese Kontexte in Ordnung sein sollte).

Antwort3

Ich habe in letzter Zeit mit der Bibliothek herumgespielt fillbetweenund dachte, dass sie für dieses Szenario ideal wäre.

Die Antwort ist von Jakes Antwort oben inspiriert, verwendet jedoch anstelle von gestapelten Diagrammen die fillbetweenin pgfplotsVersion 1.10 eingeführte Bibliothek.

Ausgabe:

Ausgabe


Das errorbandMakro verwendet sechs obligatorische Argumente: Name der Datentabelle, X-Spalte, Y-Spalte, Fehlerspalte, Linien- und Fehlerbandfarbe und Fehlerbandopazität.

Dies funktioniert, indem unsichtbare Hilfsdiagramme für die oberen und unteren Grenzen des Fehlers erstellt und für die Verwendung durch die fillbetweenBibliothek benannt werden. fillbetweenverwendet die Farb- und Opazitätsargumente als Fehlerbandeinstellungen. Schließlich zeichnet es die y-Spalte über dem Fehlerband in der bereitgestellten Farbe auf.

Die Hilfsdiagramme und Fehlerbanddiagramme fillbetweenwerden vergessen, so dass sie nicht in die Legende aufgenommen werden. Dies erleichtert die Verwendung errorbandunmittelbar im Anschluss \addlegendentry(oder \legendam Ende) zur Generierung einer Legende.

(Daten nicht angezeigt.)

Lösung:

\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}

Überlegungen zur Leistung:

Für diejenigen, die noch lesen: Ich nehme an, dass das Plotten der unsichtbaren Plots nur, um sie zu benennen, dies weniger effizient macht, als es sein könnte. Wenn jemand einen Weg kennt, dies zu ersetzen:

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

mit etwas wie:

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

es wäre großartig. Ich gehe davon aus, \pathdass das Zeichnen keine Zeit verschwendet, was es effizienter machen würde. Ich bin mir nicht sicher, wie das geht oder ob es die Effizienz verbessern würde.

verwandte Informationen