
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 \addplot
Befehle 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
mesh
Sie 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:
Bei kleineren Datensätzen können Markierungen die Übergänge verbergen:
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 mesh
Diagramm einzelne Liniensegmente zeichnet und (b) \pgfplotspointmetatransformed
die point meta
Daten vollständig normalisiert enthält: Der kleinste Metadateneintrag (hier 0,1) erhält \pgfplotspointmetatransformed=0
und der größte (hier 0,5) erhält \pgfplotspointmetatransformed=1000
. Die Werte dazwischen werden linear interpoliert. Folglich können wir sie line width
wie 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 fillbetween
und 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 fillbetween
in pgfplots
Version 1.10 eingeführte Bibliothek.
Ausgabe:
Das errorband
Makro 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 fillbetween
Bibliothek benannt werden. fillbetween
verwendet 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 fillbetween
werden vergessen, so dass sie nicht in die Legende aufgenommen werden. Dies erleichtert die Verwendung errorband
unmittelbar im Anschluss \addlegendentry
(oder \legend
am 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, \path
dass 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.