# Bar chart from CSV file with adjustable bar width

I have a CSV file with approximately 1500 records that I would like to plot using something like a bar chart, but I don't know where to start at all.

Each record contains a width and a height, which needs to be translated into the width and height of the bars. The bars then need to be arranged side by side without space in between.

The total accumulative width is about 50k units, and the maximum height is about 205k. The y-axis (height) should have a logarithmic scale, since most height values are <10k. I hope to scale the whole thing to about 1 x 0.75 * a page's available width.

I also would like a scale on the x- and y-axes that is readably large when scaled.

CSV example:

height,width
1,884
2,5768
3,835
7,2661
10,492
11,1349
...

• Yes. The next bar should be 2 units high and 5768 units wide. Altogether there are ca. 1500 bars Jan 9, 2014 at 10:31
• I think you should show what you have try so far and give a MWE as states the guidelines.
– G M
Jan 9, 2014 at 12:18

You can use the create on use mechanism to generate a new column on the fly that contains the cumulative widths of the bars, and use that together with the ybar interval plot style to generate the plot:

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}

\begin{filecontents}{data.csv}
height,width
1,884
2,5768
3,835
7,2661
10,492
11,1349
11,0
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot [ybar interval, fill=yellow] table [
col sep=comma,
create on use/xaccum/.style={
create col/expr=\pgfmathaccuma+\prevrow{width}
},
x=xaccum, y=height
] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}

• Great solution. All I changed for my own drawing was the {axis}-line: \begin{axis}[ymode=log] Jan 10, 2014 at 12:46

Is quite a strange type of data, up to my knowledge I can't find any pure TeX solution (I hope some TeX expert will find one as you post a MWE) so in the meanwhile what I propose to you is to rearrange the data to a new .csvthat can be handle more easily. Normally what you need are ranges like in this example from pgfplots manual.

You can see in \addplot coordinates that the intervals are given by the xvalues of two adjacent tuples e.g 0,0.1 for the first, 0.1,0.3 for the second and so on. Note that the last two yvalues are the same (1.5,1.5) this allow you to display the last bar. So you can rearrange your data with a Python script like this one:

import csv #note I don't use pandas or numpy so you can easy use this sciprt with a standard python interpreter
width=['width',0] #not I've add the 0 value
height=[]
widthraw=[]
with open(r'/Users/user/Desktop/testdata.csv') as f:
height =[i.split(',')[0] for i in f] #extract height
with open(r'/Users/user/Desktop/testdata.csv') as f:
widthraw=[i.split(',')[1].strip() for i in f] #extract width
for i in range(1,len(widthraw)): #skip first line and start from the number values
width.append(int(width[i])+int(widthraw[i])) #now this line add the previous value to the next
height.append(height[-1])# add the last value to include the last bar
result=zip(width,height)# make final list like [[x,y],[x1,y1],...] just what we need

with open(r'/Users/user/Desktop/result.csv','w') as f:
writer = csv.writer(f)
writer.writerows(result)


Now you should insert the result.csvin the latex document file. This is simple instead of \addplot coordinates you will use \addplot table.

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents} %this is here for make a MWE see file contents documentation

\begin{filecontents}{result.csv}
width,height
0,1
884,2
6652,3
7487,7
10148,10
10640,11
11989,11
\end{filecontents}

\begin{document}
\begin{tikzpicture} \begin{axis}[ybar interval,%this is the type of barplot
xtick=data,
xticklabel interval boundaries,%set the x label to be the boundaries
x tick label style=
{rotate=90,anchor=east}
]
\addplot table [x=width, y=height, col sep=comma] {result.csv}; %extract witdth and assing it to x and height and assing it to y the separator is comma take the result.csv in the same folder of your .tex when you will not use filecontents.
\end{axis}
\end{tikzpicture}
\end{document}


The final output is this: