Tag Archives: Bar Chart

D3 and Ajax: Updating a Bar Chart With New Data

28 Dec

This is the site I will build.

I have been showing several examples of graphing – mostly using Matplolib. In this example, I will show a bar chart in a webpage using D3 and updated via Ajax requesting a text file with the data. I also have a simple python file that randomly generates 20 data points and feeds it to the text file – my host doesn’t allow me to run the python, but you can get the idea.

I took the code from examples by Scott Murray, and some standard Ajax code block off W3. Making a few changes I was able to get it to work. I like to modify existing code to get a feel for what affects what and how things work. This really helps it all sink in.

This draws the first bar chart when the page loads.

var dataset=[12, 10, 13, 19, 21, 25, 22, 18, 15, 13, 11, 12, 15, 20, 18, 17, 16, 18, 23, 25];
var w = 500;
var h = 100;
var barPadding = 1;

var svg = d3.select(“body”)
.append(“svg”)
.attr(“width”, w)
.attr(“height”, h);

svg.selectAll(“rect”)
.data(dataset)
.enter()
.append(“rect”)
.attr(“x”, function(d, i) {
return i * (w / dataset.length);
})
.attr(“y”, function(d) {
return h – (d * 4);
})
.attr(“width”, w / dataset.length – barPadding)
.attr(“height”, function(d) {
return d * 4;
})
.attr(“fill”, “teal”);

This is my onclick function that uses Ajax and updates the chart:

function clicked(url)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
}
xmlhttp.open(“GET”,url,false);
xmlhttp.send(null);
var newd=xmlhttp.responseText;
var da=newd.split(‘,’);
for (var i in da){
da[i] = parseInt(da[i], 10)
}
document.getElementById(‘test’).innerHTML=xmlhttp.responseText;
svg.selectAll(“rect”)
.data(da)
.attr(“x”, function(d, i) {
return i * (w / da.length);
})
.attr(“y”, function(d) {
return h – (d * 4);
})
.attr(“width”, w / da.length – barPadding)
.attr(“height”, function(d) {
return d * 4;
})
.attr(“fill”, “teal”);
}

All I am doing is requesting a text file of data values (12,34,65,67,32,21,10…), then I split it in to numbers and convert to integers. I also print out the values, but that was just a check for me to see what was being returned. The rest is from an example by Scott Murray on clicking a paragraph to change the data – but with the variable hard coded in the JavaScript. I just passed the textfile to the variable and viola!

Connect the function to a button: <button type=”button” onclick=”clicked(‘data.txt’)”>Click
Me</button>.

My goal was to see how I could have a python file write out a data file and then load it in a webpage, but be able to update the data without refreshing everything on the page.  Could have done it all in Python, with Flask and Jinja but I don’t have a production setup for this. This was the most reasonable way to connect what I may be able to run in production.  Here is a python file that feeds random integers from 5 to 25 to a text file – the one that we will load in.

import random
data=open(“data2.txt”,”w+”)
x=0
for x in range(20):
i=random.randint(5,25)
if x==19:
data.write(str(i))
break
else:
data.write(str(i)+”,”)

data.close()

This could connect to MongoDB, SQLite, or generate data on the fly like it’s doing now. The principle is the same – do something and write it out to text.

Matplotlib Bar Chart

21 Dec
Simple Bar Chart

Simple Bar Chart

I did a post on Pandas and plotting. In that post, Matplotlib was used from Pandas. In this post, I will show a simple bar chart in Matplotlib- sans Pandas.

Here is the code:

import matplotlib.pylab as plt

fig = plt.figure()            #create a figure
ax = fig.add_subplot(1,1,1)    # add plot
x = [2,4,6,8]         #x axis value
y = [4,8,12,16]   #Y axis: height
ax.bar(x,y, align=’center’, color=’green’) #required ax.bar(x,y)
fig.savefig(‘paul2.jpg’)      #This saves a file
#plt.show()       This shows it on the screen and gives you the option to save.

That’s it. I like centering my bars, but leave the options out and it will align the left corner with the value of X.  Don’t forget a title – I did. Put fig.suptitle(‘Sample With YERR=2′, fontsize=14, fontweight=’bold’) before adding the subplot. And lastly I like to add the error bars using ax.bar(x,y, yerr=2, align=’center’, color=’green’). The result looks like this:

With a Title.

With a Title.

UPDATE: I hate that the bars go to the top of the chart. fix that by setting the Y Limit. Drop this line in your code: p.ylim(2,20)

Y Limit Set: Much Nicer

Y Limit Set: Much Nicer