在一个图表中制作两个图表

在一个图表中制作两个图表

我们想在 Latex 中制作下面的图表,但发现编写代码很困难。

当我们尝试在 var 中定义 fm 时,由于 fm 不是数字,因此无法编译。如果我们仅插入数字,则表格将正确生成。

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}

    \begin{tikzpicture}
    \pgfplotstableread{
    var Cat1 Cat2 
    fm 10 50 
    fc0 -40 60 
    ft0  -20 60 
    fvr 10 50 
    E0 -40 60 
    E90  -20 60
    G0 10 50 
    G90 -40 60 
    CM  -20 60 
    XR 10 50 
    GK1 -40 60 
    Gk2  -20 60
    GK3 10 50 
    Qk -40 60 
    Wk  -20 60
    }\mytable
    \begin{axis}[
    xbar stacked,
    % is default anyway:
    stack negative=separate,
    %
    /pgf/number format/1000 sep=,
    xmajorgrids,
    nodes near coords,
    nodes near coords style={font=\tiny},
    ytick distance=1,
    legend style={at={(0.5,-0.1)},
    anchor=north,legend columns=-1},
    extra x ticks={0},
    extra x tick style={grid style={black},
    xticklabel=\empty},
    ]
    \addplot table [x index=1,y=var] {\mytable};
    \addplot table [x index=2,y=var] {\mytable};
    \legend{Cat1,Cat2}
    \end{axis}
    \end{tikzpicture}

\end{document}

答案1

好的,这是所有相关元素的草图,仅使用基本元素Tikz。我故意省略了所有压缩代码的方法,使用\forach循环等。这样做的目的是让它保持简单,并且足够容易调整和扩展,以便 Latex/Tikz 的初学者使用。

让我们看一下结果和代码的相关部分。你可能需要查阅手册或多或少是并行的。

结果

开始

\documentclass[10pt,border=3mm,tikz]{standalone}
\usepackage{amsmath}% for the partial derivatives
  • 自动加载 tikz
  • 创建一个具有合适宽度和高度的 pdf
  • graphicx稍后通过包将此pdf 包含\includegraphics到你的论文中,这样它就会保持为矢量图像
  • amsmath\partial只是为您的图例提供了很好的支持

布局和数据

只需将数据乘以 10 即可获得厘米,并将所有内容设置为绝对坐标(大多数情况下)。以下是如何绘制外框:

    % ~~~ outer box ~~~~~~~~~~~~~~
    \draw (-12,0) rectangle +(24,15);
  • 从 (-12,0) (左下角)开始
  • 在那里放一个矩形
  • 使用相对坐标(+),即添加 24 厘米水平和 15 厘米垂直;您也可以计算绝对端点,但这更容易
  • 你可能想改变它line width,例如thick

网格

非常相似,但 x 方向的步数增加了:

    % ~~~ grid ~~~~~~~~~~~~~~
    \draw[gray!50] (-12,0) grid[xstep=5] +(24,15);

数据条和样式

事实证明,最好在左边画一个矩形,在右边画另一个矩形。 y 值从下到上仅增加 1 厘米,其中 -9 厘米对应左侧数据的 0.9,.3 为矩形的高度:

    \draw[dy] (0,14) rectangle +(-9,.3); \draw[py] (0,14) rectangle +( 4,.3);

这两个样式语句和所有其他语句都是在开头定义的:

 \begin{tikzpicture}[% ~~~ self-defined styles ~~~~~
        dy/.style={fill=brown!70},
        py/.style={fill=brown!30},
        lbl/.style={font={\Huge}},
        ylbl/.style={lbl, anchor=east},% for y-axis, but I like lbl more (centered)
    ]

因此,您在此处应用的任何更改都适用于整个图表:

  • dypy只需定义并应用填充颜色
  • lblylbl关注的是放置标签文本

我故意让数据条“在网格上游动”,因为太懒,所以可能创造了一些有趣的视觉效果。

x 标签

直截了当:

    % ~~~ some x-labels ~~~~~~~~~~~~~
    \node[lbl] at (-10,-1) {1};
    \node[lbl] at (-5,-1)  {0.5};
    \node[lbl] at ( 10,-1) {1};
    \node[lbl] at ( 5,-1)  {0.5};

y 标签

类似地,旋转 y 方向的文本:

    % ~~~ y-labels ~~~~~~~~~~~~~
    \node[lbl] at (-13,14) {$f_{c,0}$};
    \node[lbl] at (-13,6) {$X_R$};
    \node[lbl] at (-13,3) {$G_{k3}$};
    \node[lbl] at (-13,2) {$Q_k$};
    \node[lbl] at (-13,1) {$W_k$};
    
    \node[lbl,rotate=90] at (-15,6) {Stochastic variable X};

如果要将标签与其右边缘对齐,请使用ylbl,将节点设置anchor pointeast,即中间右侧。

如您所见,节点可以在内部保存任何 Latex 文本{ },例如使用数学模式的数学文本$ ... $

最后:传奇

也不是很令人兴奋:

    % ~~~ legend ~~~~~~~~~~~~~~~~
    \node[lbl] at (0,-2) {\%};
    %     partials
    \draw[dy] (-5,-4) rectangle +(1,1) 
        node[lbl,anchor=west,shift=(-35:1)] 
            {$\frac{\partial\beta}{\partial\mu}\ \frac{\mu}{\beta}$};
    \draw[py] ( 2,-4) rectangle +(1,1) 
        node[lbl,anchor=west,shift=(-35:1)] 
            {$\frac{\partial\beta}{\partial\sigma}\ \frac{\sigma}{\beta}$};
  • \draw选择起点
  • 把 arectangle当作正方形
  • 在完成此路径(带有;)之前,放置另一个节点(带有文本)
  • 在极坐标中移动这个节点,shift=(-35:1)以便更好地定位数学
  • 放入一些偏导数
  • 请在\中间插入一个空格,从视觉上将两个分数分开
  • 完成路径;

完整代码:

\documentclass[10pt,border=3mm,tikz]{standalone}
\usepackage{amsmath}% for the partial derivatives

\begin{document}
 \begin{tikzpicture}[% ~~~ self-defined styles ~~~~~
        dy/.style={fill=brown!70},
        py/.style={fill=brown!30},
        lbl/.style={font={\Huge}},
        ylbl/.style={lbl, anchor=east},% for y-axis, but I like lbl more (centered)
    ]
    % ~~~ outer box ~~~~~~~~~~~~~~
    \draw (-12,0) rectangle +(24,15);
    % ~~~ grid ~~~~~~~~~~~~~~
    \draw[gray!50] (-12,0) grid[xstep=5] +(24,15);
    % ~~~ some bars ~~~~~~~~~
    \draw[dy] (0,14) rectangle +(-9,.3); \draw[py] (0,14) rectangle +( 4,.3);
    \draw[dy] (0, 7) rectangle +( 0,.3); \draw[py] (0, 7) rectangle +( 0,.3);   
    \draw[dy] (0, 6) rectangle +(-6,.3); \draw[py] (0, 6) rectangle +(.1,.3);   
    \draw[dy] (0, 1) rectangle +(-1,.3); \draw[py] (0, 1) rectangle +( 4,.3);   
    % ~~~ some x-labels ~~~~~~~~~~~~~
    \node[lbl] at (-10,-1) {1};
    \node[lbl] at (-5,-1)  {0.5};
    \node[lbl] at ( 10,-1) {1};
    \node[lbl] at ( 5,-1)  {0.5};
    % ~~~ y-labels ~~~~~~~~~~~~~
    \node[lbl] at (-13,14) {$f_{c,0}$};
    \node[lbl] at (-13,6) {$X_R$};
    \node[lbl] at (-13,3) {$G_{k3}$};
    \node[lbl] at (-13,2) {$Q_k$};
    \node[lbl] at (-13,1) {$W_k$};
    
    \node[lbl,rotate=90] at (-15,6) {Stochastic variable X};
    
    % ~~~ legend ~~~~~~~~~~~~~~~~
    \node[lbl] at (0,-2) {\%};
    %     partials
    \draw[dy] (-5,-4) rectangle +(1,1) 
        node[lbl,anchor=west,shift=(-35:1)] 
            {$\frac{\partial\beta}{\partial\mu}\ \frac{\mu}{\beta}$};
    \draw[py] ( 2,-4) rectangle +(1,1) 
        node[lbl,anchor=west,shift=(-35:1)] 
            {$\frac{\partial\beta}{\partial\sigma}\ \frac{\sigma}{\beta}$};
 \end{tikzpicture}
\end{document}

PS:让这段代码更紧凑、更通用

让我们介绍一些循环,像这样:

    \foreach \x [count=\i] in {1, .2, .1, .2, .3, 6, 0,0, 1,0,1,0,0,9,0}
        \draw[dy] (0, \i) rectangle +(-\x,.3);
  • 它遍历给定的列表{1, .2, ... 0}
  • 将每个元素分配给\x每个循环
  • 并将元素计数为\i(1、2、3、...)
  • 使用它们进行路径构造,例如在\draw或稍后的\node
  • \x当然,数据是根据你的截图粗略估计的

结果2

 % ~~~ making things more compact ~~~~~~~~~~~~~~~~~
 \begin{tikzpicture}[% ~~~ self-defined styles ~~~~~
        dy/.style={fill=brown!70,yshift=-1.5mm},% "centering" swimming bar
        py/.style={fill=brown!30,yshift=-1.5mm},
        lbl/.style={font={\Huge}},
        ylbl/.style={lbl, anchor=east},% for y-axis, but I like lbl more (centered)
    ]
    % ~~~ grid ~~~~~~~~~~~~~~
    \draw[gray!50] (-12,0) grid[xstep=5] +(24,16);
    % ~~~ outer box ~~~~~~~~~~~~~~
    \draw[line width=5pt] (-12,0) rectangle +(24,16);
    % ~~~ all bars ~~~~~~~~~~~~~~~~~~~~~~
    \foreach \x [count=\i] in {1, .2, .1, .2, .3, 6, 0,0, 1,0,1,0,0,9,0}
        \draw[dy] (0, \i) rectangle +(-\x,.3);
    \foreach \x [count=\i] in {4,0,0,0,0,.3,0,0,.1,0,.09,0,0,4,0}
        \draw[py] (0, \i) rectangle +(\x,.3);
    % ~~~ some x-labels, saving lines ~~~~~~~~~~~~~
    \node[lbl] at (-10,-1) {1}   node[lbl] at (-5,-1)  {0.5};
    \node[lbl] at ( 10,-1) {1}; \node[lbl] at ( 5,-1)  {0.5};
    % ~~~ y-labels ~~~~~~~~~~~~~
    \foreach \t [count=\i] in { W_k, Q_k, G_{k3}, G_{k2}, G_{k1}, X_R, C_M,
                G_{90}, G_0, E_{90}, E_0, f_{v,r}, f_{t,0}, f_{c,0}, f_m }
        \node[lbl] at (-13,\i) {$\t$};  
    \node[lbl,rotate=90] at (-15,6) {Stochastic variable X};
    % ~~~ legend ~~~~~~~~~~~~~~~~
    \node[lbl] at (0,-2) {\%};
    %     partials
    \draw[dy] (-5,-4) rectangle +(1,1) 
        node[lbl,anchor=west,shift=(-35:1)] 
            {$\frac{\partial\beta}{\partial\mu}\ \frac{\mu}{\beta}$};
    \draw[py] ( 2,-4) rectangle +(1,1) 
        node[lbl,anchor=west,shift=(-35:1)] 
            {$\frac{\partial\beta}{\partial\sigma}\ \frac{\sigma}{\beta}$};
 \end{tikzpicture}

答案2

另一种可能性是直接使用表中给出的数据。为了fm不出现错误并正确对齐刻度,您必须添加三项内容:

  1. \addplot table [x index=1,y expr=\coordindex] {\mytable};,其中y expr=\coordindex给出 y 坐标的对应值 (0, 1, 2 ... 14)。
  2. yticklabels from table={\mytable}{var},因此 y 坐标获取表中的“文本值”。
  3. 此时,您会看到一些内容,但fm缺少与第一个变量(即)对应的标签。要添加它,您必须y ticks相应地定义。由于您有 15 个变量,因此您可以在轴中写入ytick={0,...,14},

编辑:并注意pgfplotstable序言中的!

其结果(+X 轴和 Y 轴上的标签)如下。您可以看到它需要微调才能实现所需的图形,例如分离/减小不同条形的宽度并更改其颜色。

在此处输入图片描述

以及对应的代码:

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{pgfplotstable}

\begin{document}
    
    \begin{tikzpicture}
        \pgfplotstableread{
            var Cat1 Cat2 
            fm 10 50 
            fc0 -40 60 
            ft0  -20 60 
            fvr 10 50 
            E0 -40 60 
            E90  -20 60
            G0 10 50 
            G90 -40 60 
            CM  -20 60 
            XR 10 50 
            GK1 -40 60 
            Gk2  -20 60
            GK3 10 50 
            Qk -40 60 
            Wk  -20 60
        }\mytable
        \begin{axis}[
            xbar stacked,
            % is default anyway:
            stack negative=separate,
            %
            /pgf/number format/1000 sep=,
            xmajorgrids,
            nodes near coords,
            nodes near coords style={font=\tiny},
            ytick distance=1,
            legend style={at={(0.5,-0.2)},
                anchor=north,legend columns=-1},
            extra x ticks={0},
            extra x tick style={grid style={black},
                xticklabel=\empty},
            yticklabels from table={\mytable}{var}, % <- added code
            ytick={0,...,14},% <- added code
            xlabel = {\%},
            ylabel = {Stochastic variable X},
            bar width = 0.25cm, % Controls bar width
            ]
            \addplot table [x index=1,y expr=\coordindex] {\mytable}; % <- added code
            \addplot table [x index=2,y expr=\coordindex] {\mytable}; % <- added code
            \legend{$\frac{\partial\beta}{\partial\mu}\ \frac{\mu}{\beta}$,$\frac{\partial\beta}{\partial\sigma}\ \frac{\sigma}{\beta}$}
        \end{axis}
    \end{tikzpicture}
    
\end{document}

相关内容