I’m quite satisfied with what i did yesterday so decided to share.

Image is cropped to avoid wordpress scaling it. Observe how the bars are neatly stacked one to next having a gap between of exactly one pixel

Now, one pixel wide lines sometimes can get real handy when you want to have crisp graphics.
In the example below there are three attempts into doing that.
I drew two lines, using move_to and line_to, and i also drew a rectangle, using fill_area.

First frame is what you get, when you set line width to 1, and happilly draw lines in some set points.
Something like

cr.move_to(10, 10)
cr.line_to(10, 30)

It might not be obvious due to the 400% scaling i’ve done on the example, but the result is 2 half-colored lines, as the Cairo’s FAQ will explain.
Observe though, that does not involve sharpness of the fill_area. How neat!

After reading the FAQ – one like me might think – how about i just move the whole thing by half pixel!
That is what is depicted in the second example. Lines are now almost sharp, except for the starts and ends. Result of fill_area is screwed though.

So no, you can’t just shift everything by half pixel. The proper way is exactly how the FAQ tells you – move the lines (and just lines, apparently) by half pixel “in appropriate direction”, where appropriate is – if the line is horizontal, move it half pixel down. If it is vertical – move it half pixel right.

There is other way out though – disabling the antialiasing. It could be a bug, but on some boxes that causes the unsharp lines not to appear at all nowadays. So better don’t do that. We had a bug on that.

But let’s now look on the bars!
I’ll repeat the image:

It seems like nothing, but i dare you to draw 18 sharp bars in 300 pixels, having a gap in between of 1px exactly – it’s not quite just calculating the bar width and then dashing away – there are fractions, and this is what this post is about.
In the given task the average bar width should be 300 / 18 ~= 16.67pixels.
But we can’t draw those non-round pixels sharply. So what we could do first, is round the thing to either one or the other side. In this case we could do the task either in 288 pixels (18*16) or 306 pixels (18*17).
All good, but we would like the bars to fill up the 300 pixel area, and preferrably up until the last pixel, because it looks nice so! Also, if you would resize our 300 pixel wide area to some other size, you would be able to jump only from one state to the next. And the more bars you would get, the bigger the jumps would be at the end.

Yesterday I realized that all we should care here about, is to have those bars sharp (that means drawn at exact coordinates) and the one pixel gap between. The area where we can variate, is the bar width itself – the eye won’t notice if one bar suddenly is 17, not 18 pixels, especially since they are not horizontally aligned.

So the final algorithm is simple:
Calculate the average bar size (split width by bar numbers) and round it down. After drawing a bar, recalculate the average size again with remaining width and bar count. And so until done. Save all the x and width positions per value to know where to draw other stuff, like labels and such.

Here’s the code from the commit:

# calculate position of each bar
# essentially we care more about the exact 1px gap between bars than about the bar width
# so after each iteration, we adjust the bar width
x = graph_x
exes = {}
adapted_bar_width = bar_width
for i, (current_time, total) in enumerate(self.tick_totals):
    exes[current_time] = (x, round(adapted_bar_width)) #saving those as getting pixel precision is not an exact science
    x = round(x + adapted_bar_width)
    adapted_bar_width = (self.width - x) / float(max(len(self.tick_totals) - i - 1, 1))

Now i’ll have to fix the charting library.