Выход:

Выход:

У меня есть несколько кривых/наборов данных (полученных из моделирования Монте-Карло) с ошибками y, зависящими от x, которые я хотел бы построить с указанием ошибок. Поскольку каждая кривая состоит из довольно большого количества точек данных с довольно небольшими ошибками, использование обычных планок погрешностей не кажется наиболее информативным/эстетичным решением. Вместо этого, я думаю, было бы лучше указать ошибку (локальной) толщиной линии (или толщиной в направлении y). Это можно сделать, например, построив графики y(x)+dy(x) и y(x)-dy(x) и заполнив пространство между двумя кривыми. Но как это сделать (достаточно простым способом - помните: у меня несколько кривых!) в Pgfplots?

Мой вопрос, возможно, чем-то похож наВот этот, но я не знаю, как выполнить необходимые в моем случае манипуляции с таблицами (в Pgfplots).

Вот упрощенный пример того, как выглядят мои файлы данных:

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

решение1

Вы можете использовать стековые графики для рисования полос неопределенности перед тем, как построить фактическую линию данных. Сначала вы бы сказали \addplot table [y expr=\thisrow{<data col>}-\thisrow{<error col}] {<datatable>};определить нижнюю границу, а затем \addplot [fill=<colour>] table [y expr=2*\thisrow{<error col}] {<datatable>} \closedcycle;заполнить область между нижней и верхней границей.

Эти две \addplotкоманды можно объединить в макрос для создания графиков следующим образом:

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

вы можете создать график с полосой ошибок, используя

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

Ниже приведен пример построения графикаСредняя площадь морского льда на севере и юге.

Феттерер, Ф., К. Ноулз, В. Мейер, М. Савойя и А. К. Винднагель. 2017, ежедневное обновление. Индекс морского льда, версия 3. [Данные/Север+Юг/Месяц]. Боулдер, Колорадо, США. NSIDC: Национальный центр данных по снегу и льду. 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}

ОБНОВЛЯТЬ

Имеющиеся в настоящее время данные охватывают среднюю протяженность морского льда с 1981 по 2010 год. Для воспроизводимости код LaTeX можно обновить следующим образом (исключая линейные графики NH и 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};

решение2

Можно использовать meshграфик с изменяющимся line width. Однако это приводит к неплавным переходам от одного сегмента линии к другому. Но, возможно, это осуществимо:

введите описание изображения здесь

Если у вас небольшие наборы данных, маркеры могут скрыть переходы:

введите описание изображения здесь

Вот код:

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

Основная идея заключается в том, что (a) meshграфик рисует отдельные сегменты линии и (b) \pgfplotspointmetatransformedсодержит point metaданные в полностью нормализованном виде: наименьшая запись метаданных (здесь 0,1) получает , \pgfplotspointmetatransformed=0а наибольшая (здесь 0,5) получает \pgfplotspointmetatransformed=1000. Значения между ними интерполируются линейно. Следовательно, мы можем безопасно использовать их для, line widthкак указано выше.

Обратите внимание, что параметры оцениваются в контекстах, где этот макрос point meta недоступен. С этой целью я определил его как 1000 глобально (что должно быть нормально для этих контекстов).

решение3

В последнее время я экспериментировал с fillbetweenбиблиотекой и подумал, что она идеально подойдет для этого сценария.

Ответ основан на ответе Джейка выше, но вместо составных графиков используется fillbetweenбиблиотека, представленная в версии 1.10.pgfplots

Выход:

Выход


Макрос errorbandпринимает шесть обязательных аргументов: имя таблицы данных, столбец x, столбец y, столбец ошибок, цвет линии и полосы ошибок, а также непрозрачность полосы ошибок.

Он работает, создавая невидимые вспомогательные графики для верхней и нижней границ ошибки и называя их для использования библиотекой fillbetween. fillbetweenиспользует аргументы цвета и непрозрачности в качестве настроек полосы ошибки. Наконец, он строит столбец y поверх полосы ошибки, используя предоставленный цвет.

Вспомогательные графики и fillbetweenграфики полосы ошибок забываются, так что они не включены в легенду. Это позволяет легко использовать их errorbandсразу после \addlegendentry(или \legendв конце) для создания легенды.

(Данные не показаны.)

Решение:

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

Соображения производительности:

Для тех, кто все еще читает, я предполагаю, что построение невидимых графиков только для того, чтобы назвать их, делает это менее эффективным, чем могло бы быть. Если кто-то знает способ заменить это:

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

что-то вроде:

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

было бы здорово. Я предполагаю, \pathчто на самом деле не тратит время на рисование, что делает его более эффективным. Не уверен, как это сделать, и даже повысит ли это эффективность.

Связанный контент