TransWikia.com

Pgfplots: Discrete instead of connected values

TeX - LaTeX Asked on June 14, 2021

I have a table with experimental data. The table has two columns separated by a semicolon. The first column is the value for the x-axis and the second one is the y-axis value.

If I use the general addplot table {} command, pgfplots draws a plot where it connects the points together. As the data points in question are discrete values, there should not be a connection between them, but rather should every point be drawn independently.

What’s the correct approach for this using pgfplots?

Output generated by the addplot table {} command

default output

documentclass{article}

usepackage{pgfplots}
pgfplotsset{compat = 1.17}
usepackage{siunitx}

begin{filecontents}{table.csv}
    57.7200;403.7083
    81.1200;359.9954
    83.7600;2673.1575
    84.4800;201.8542
    95.7600;359.9954
    104.6400;403.7083
    104.8800;2673.1575
    105.0000;5146.4829
    105.1200;11393.4863
    105.2400;5706.3101
    105.9600;201.8542
    106.9200;4277.3057
    107.2800;359.9954
    107.4000;682.9842
    107.8800;2673.1575
    108.0000;403.7083
    108.3600;2673.1575
    108.6000;201.8542
    109.2000;47.6190
    109.4400;3883.1460
    109.9200;4081.7891
    110.0400;1113.2275
end{filecontents}


begin{document}

begin{tikzpicture}
    
    begin{axis}[
        xlabel = {textit{m/z}},
        ylabel = {Int. [si{cps}]},
    ]
        addplot+[mark = none, red] table[
            col sep = semicolon
        ] {table.csv};
    end{axis}

end{tikzpicture}

end{document}

Expected output

expected output

This output was generated by a little "hack". To have the correct axis, I drew the plot as before but changed the color to red!0 so that it is transparent. Then, for each table entry, I manually drew the lines with the draw command. It goes without mentioning, that this is not optimal, but at least it illustrates the desired output.

documentclass{article}

usepackage{pgfplots}
pgfplotsset{compat = 1.17}
usepackage{siunitx}

begin{filecontents}{table.csv}
    57.7200;403.7083
    81.1200;359.9954
    83.7600;2673.1575
    84.4800;201.8542
    95.7600;359.9954
    104.6400;403.7083
    104.8800;2673.1575
    105.0000;5146.4829
    105.1200;11393.4863
    105.2400;5706.3101
    105.9600;201.8542
    106.9200;4277.3057
    107.2800;359.9954
    107.4000;682.9842
    107.8800;2673.1575
    108.0000;403.7083
    108.3600;2673.1575
    108.6000;201.8542
    109.2000;47.6190
    109.4400;3883.1460
    109.9200;4081.7891
    110.0400;1113.2275
end{filecontents}


begin{document}

begin{tikzpicture}
    
    begin{axis}[
        xlabel = {textit{m/z}},
        ylabel = {Int. [si{cps}]},
    ]
        addplot+[mark = none, red!0] table[
            col sep = semicolon
        ] {table.csv};
        draw[red] (57.7200,0) -- (57.7200,403.7083);
        draw[red] (81.1200,0) -- (81.1200,359.9954);
        draw[red] (83.7600,0) -- (83.7600,2673.1575);
        draw[red] (84.4800,0) -- (84.4800,201.8542);
        draw[red] (95.7600,0) -- (95.7600,359.9954);
        draw[red] (104.6400,0) -- (104.6400,403.7083);
        draw[red] (104.8800,0) -- (104.8800,2673.1575);
        draw[red] (105.0000,0) -- (105.0000,5146.4829);
        draw[red] (105.1200,0) -- (105.1200,11393.4863);
        draw[red] (105.2400,0) -- (105.2400,5706.3101);
        draw[red] (105.9600,0) -- (105.9600,201.8542);
        draw[red] (106.9200,0) -- (106.9200,4277.3057);
        draw[red] (107.2800,0) -- (107.2800,359.9954);
        draw[red] (107.4000,0) -- (107.4000,682.9842);
        draw[red] (107.8800,0) -- (107.8800,2673.1575);
        draw[red] (108.0000,0) -- (108.0000,403.7083);
        draw[red] (108.3600,0) -- (108.3600,2673.1575);
        draw[red] (108.6000,0) -- (108.6000,201.8542);
        draw[red] (109.2000,0) -- (109.2000,47.6190);
        draw[red] (109.4400,0) -- (109.4400,3883.1460);
        draw[red] (109.9200,0) -- (109.9200,4081.7891);
        draw[red] (110.0400,0) -- (110.0400,1113.2275);
    end{axis}

end{tikzpicture}

end{document}

2 Answers

I think you are looking for ycomb.

documentclass{article}

usepackage{pgfplots}
pgfplotsset{compat = 1.17}
usepackage{siunitx}

begin{filecontents}[overwrite]{table.csv}
    57.7200;403.7083
    81.1200;359.9954
    83.7600;2673.1575
    84.4800;201.8542
    95.7600;359.9954
    104.6400;403.7083
    104.8800;2673.1575
    105.0000;5146.4829
    105.1200;11393.4863
    105.2400;5706.3101
    105.9600;201.8542
    106.9200;4277.3057
    107.2800;359.9954
    107.4000;682.9842
    107.8800;2673.1575
    108.0000;403.7083
    108.3600;2673.1575
    108.6000;201.8542
    109.2000;47.6190
    109.4400;3883.1460
    109.9200;4081.7891
    110.0400;1113.2275
end{filecontents}


begin{document}

begin{tikzpicture}
    
    begin{axis}[
        xlabel = {textit{m/z}},
        ylabel = {Int. [si{cps}]},
    ]
        addplot+[mark = none, red,ycomb] table[
            col sep = semicolon
        ] {table.csv};
    end{axis}

end{tikzpicture}

end{document}

enter image description here

Correct answer by user227987 on June 14, 2021

As shown in anonymous' answer, ycomb can do the job. Another way is to use ybar. This plots each data point as a vertical bar (for horizontal bars, you would use xbar). The bar width can be customized using bar width, as in:

begin{axis}[..., ybar, bar width=0.4pt]
    addplot table[draw=none] {table.csv};
end{axis}

As you found out yourself, draw=none allows one to get the precise specified width for the bars, otherwise they are drawn slightly larger due to the draw operation.

Full example:

documentclass{article}
usepackage{pgfplots}
pgfplotsset{compat=1.17}
usepackage{siunitx}

begin{filecontents}{table.csv}
    57.7200;403.7083
    81.1200;359.9954
    83.7600;2673.1575
    84.4800;201.8542
    95.7600;359.9954
    104.6400;403.7083
    104.8800;2673.1575
    105.0000;5146.4829
    105.1200;11393.4863
    105.2400;5706.3101
    105.9600;201.8542
    106.9200;4277.3057
    107.2800;359.9954
    107.4000;682.9842
    107.8800;2673.1575
    108.0000;403.7083
    108.3600;2673.1575
    108.6000;201.8542
    109.2000;47.6190
    109.4400;3883.1460
    109.9200;4081.7891
    110.0400;1113.2275
end{filecontents}

begin{document}

begin{tikzpicture}
    begin{axis}[
        xlabel = {textit{m/z}},
        ylabel = {Int. [si{cps}]},
        ybar, bar width = 0.4pt,
    ]
        addplot+[draw=none, fill=red] table[col sep = semicolon] {table.csv};
    end{axis}
end{tikzpicture}

end{document}

enter image description here

If you want the bar width to be equal to the current PGF line width in the tikzpicture, you can use bar width/.expanded = thepgflinewidth:

documentclass{article}
usepackage{pgfplots}
pgfplotsset{compat=1.17}
usepackage{siunitx}

begin{filecontents}{table.csv}
    57.7200;403.7083
    81.1200;359.9954
    83.7600;2673.1575
    84.4800;201.8542
    95.7600;359.9954
    104.6400;403.7083
    104.8800;2673.1575
    105.0000;5146.4829
    105.1200;11393.4863
    105.2400;5706.3101
    105.9600;201.8542
    106.9200;4277.3057
    107.2800;359.9954
    107.4000;682.9842
    107.8800;2673.1575
    108.0000;403.7083
    108.3600;2673.1575
    108.6000;201.8542
    109.2000;47.6190
    109.4400;3883.1460
    109.9200;4081.7891
    110.0400;1113.2275
end{filecontents}

begin{document}

begin{tikzpicture}[line width=2pt]
    begin{axis}[
        xlabel = {textit{m/z}},
        ylabel = {Int. [si{cps}]},
        ybar, bar width/.expanded = thepgflinewidth,
    ]
        addplot+[draw=none, fill=red] table[col sep = semicolon] {table.csv};
    end{axis}
end{tikzpicture}

end{document}

enter image description here

Answered by frougon on June 14, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP