Редактировать

Редактировать

У меня проблема в том, что на следующем графике отсутствует правый узел около текста координат A. Источник проблемы — ошибка округления в данных: они должны быть в сумме 100, но в A это немного больше. Как лучше всего этого избежать? Просто округлить A в меньшую сторону — не вариант. У меня куча таких графиков, с большим количеством столбцов, и почти в каждом есть строка с суммой, которая немного больше.

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}

\pgfplotsset{
 my stackbar plot/.style={
             xbar stacked,
             xmin=0,xmax=100,
             symbolic y coords={A,B},
             ytick=data,
             nodes near coords={xxx},}}

\begin{document}


\begin{tikzpicture}
\pgfplotstableread[col sep=space]{
text   --    -   
B      50    50
A      50.01  50
 }\data


\begin{axis}[my stackbar plot,]
 \addplot table [x expr = \thisrow{--},y=text] {\data};
 \addplot table [x expr = \thisrow{-}, y=text] {\data};
\end{axis}
\end{tikzpicture}

\end{document} 

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

решение1

Я решил, что самое разумное решение — нормализовать значения. Вот упрощенная версия кода, который я использовал в конце:

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}

\pgfplotsset{
 my stackbar plot/.style={
             xbar stacked,
             xmin=0,xmax=100,
             symbolic y coords={A,B},
             ytick=data,
             nodes near coords={xxx},}}

\begin{document}


\begin{tikzpicture}
\pgfplotstableread[col sep=space]{
text   --    -
B      50    50
A      50.01  50
 }\data

\pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}}]{sum}\data
\pgfplotstablecreatecol[create col/expr={\thisrow{--}/\thisrow{sum}*100}]{--}\data
\pgfplotstablecreatecol[create col/expr={\thisrow{-}/\thisrow{sum}*100}]{-}\data

\begin{axis}[my stackbar plot,]
 \addplot table [x expr = \thisrow{--},y=text] {\data};
 \addplot table [x expr = \thisrow{-}, y=text] {\data};
\end{axis}
\end{tikzpicture}

\end{document}

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

Редактировать

Дальнейший тест показал, что нормализации недостаточно. Сумма все еще может быть немного больше 100, и поэтому оценка может потеряться. Необходимо усечь значения, см.pgfplots: исправление проблем округления.

решение2

Также можно нормализовать только те значения в строках, сумма которых не составляет 100:

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}

\pgfplotsset{
 my stackbar plot/.style={
             xbar stacked,
             xmin=0,xmax=100,
             symbolic y coords={A,B},
             ytick=data,
             nodes near coords={xxx},}}

\begin{document}


\begin{tikzpicture}
\pgfplotstableread[col sep=space]{
text   --    -
B      50    50
A      50.01  50
 }\data

\pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}}]{sum}\data

% normalize only if the sum is not 100
\pgfplotsinvokeforeach{--,-}{%
  \pgfplotstablemodifyeachcolumnelement{#1}\of\data\as\wert{%
    \pgfplotstablegetelem{\pgfplotstablerow}{sum}\of\data%
    \pgfmathparse{\pgfplotsretval==100?\wert:\wert*100/\pgfplotsretval}%
    \edef\wert{\pgfmathresult}
  }%
}

\begin{axis}[my stackbar plot,]
 \addplot table [x expr = \thisrow{--},y=text] {\data};
 \addplot table [x expr = \thisrow{-}, y=text] {\data};
\end{axis}
\end{tikzpicture}

\end{document}

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

Таким же образом можно изменить только те значения в строках, которые в сумме составляют более 100, используя

% normalize only if the sum is >100
\pgfplotsinvokeforeach{--,-}{%
  \pgfplotstablemodifyeachcolumnelement{#1}\of\data\as\wert{%
    \pgfplotstablegetelem{\pgfplotstablerow}{sum}\of\data%
    \pgfmathparse{\pgfplotsretval<=100?\wert:\wert*100/\pgfplotsretval}%
    \edef\wert{\pgfmathresult}
  }%
}

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