So, a while ago, I’ve decided to code a library to plot some information I had.
The idea was to create simple graphics in a way they would be easy to create, beautiful and good to present to people with no or few backgrounds on math and computers.
For the ease one creation I, obviously, used Python
And, as I was already a PyCairo enthusiast (that began by the time I read Aventuras no cairo by Marcelo Lira and, as pointed out by him, this other one), I decide to use it to draw my graphics.
On this first version, the CairoPlot library provides 3 functions:
dot_line_plot()
Function to plot graphics using dots and lines as seen below.

dot_line_plot (name,
data,
width,
height,
background = None,
border = 0,
axis = False,
grid = False,
h_legend = None,
v_legend = None,
h_bounds = None,
v_bounds = None)
name - Name of the desired output file, no need to input the .svg as it will be added at runtim;
data - The list, list of lists or dictionary holding the data to be plotted;
width, height - Dimensions of the output image;
background - A 3 element tuple representing the rgb color expected for the background. If left None, a gray to white gradient will be generated;
border - Distance in pixels of a square border into which the graphics will be drawn;
axis - Whether or not the axis are to be drawn;
grid - Whether or not the gris is to be drawn;
h_legend, v_legend - lists of strings containing the horizontal and vertical legends for the axis;
h_bounds, v_bounds - tuples containing the lower and upper value bounds for the data to be plotted.
Example of Use
teste_data = [0, 1, 3, 8, 9, 0, 10, 10, 2, 1]
CairoPlot.dot_line_plot('teste', teste_data, 400, 300, axis=True)
Result:

teste_data_2 = {"john" : [10, 10, 10, 10, 30], "mary" : [0, 0, 3, 5, 15], "philip" : [13, 33, 11, 25, 2]}
teste_h_legend = ["jan/2008", "feb/2008", "mar/2008", "apr/2008", "may/2008"]
CairoPlot.dot_line_plot('teste2', teste_data_2, 400, 300, h_legend = teste_h_legend, axis = True, grid = True)
Result:

pizza_plot()
Function to plot pizza graphics.

pizza_plot(name,
data,
width,
height,
background = None)
name - Name of the desired output file, no need to input the .svg as it will be added at runtim;
data - The list, list of lists or dictionary holding the data to be plotted;
width, height - Dimensions of the output image;
background - A 3 element tuple representing the rgb color expected for the background. If left None, a gray to white gradient will be generated;
Example of Use
teste_data = {"john" : 123, "mary" : 489, "philip" : 600 , "suzy" : 235}
CairoPlot.pizza_plot("pizza_teste", teste_data, 500, 500)
Result:

gantt_chart()
Function to create Gantt Charts.

Note: the output for this function was based on the graphic seen on this post from wired.
gantt_chart(name,
pieces,
width,
height,
h_legend,
v_legend,
colors)
name - Name of the desired output file, no need to input the .svg as it will be added at runtim;
pieces - A list defining the spaces to be drawn. The user must pass, for each line, the index of its start and the index of its end. If a line must have two or more spaces, they must be passed inside a list;
width, height - Dimensions of the output image;
h_legend - A list of names for each of the vertical lines;
v_legend - A list of names for each of the horizontal spaces;
colors - List containing the colors expected for each of the horizontal spaces.
Example of Use
pieces = [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,8)]
h_legend = [ 'teste01', 'teste02', 'teste03', 'teste04']
v_legend = [ '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010' ]
colors = [ (1.0, 0.0, 0.0), (1.0, 0.7, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0) ]
CairoPlot.gantt_chart('gantt_teste', pieces, 600, 300, h_legend, v_legend, colors)
Result:

So, I think it’s ready for you guys to use. CairoPlot Google Code Project
The support is also open :D, whenever you need, feel free to contact at alf.rodrigo@gmail.com or leave a comment.
Ficou massa Alf
Fuderoso. Já tinha achado os gráficos legais, mas depois de ver a API e as imagens gerados, e como tudo é estupidamente simples, achei mais fuderoso ainda
Sem falar que o post ficou show.
Muito legal! Quando tiver um tempo vou testar
Muito bem, API simples e fácil de usar, parabéns!!!
Ficou muito bom cara, parabens.
boa… falta só agente usar na monografia pra validar =P
Só funciona com python2.5 por causa da sintaxe do for …: …. if ….. else ……? Ou estou cometendo algum erro?
Testei aqui e realmente é muito interessante e de muita boa aparência as figuras geradas. Percebi que no dot_line_plot() quando se declara menos valores dentro da lista para uma chave do dicionário (por exemplo: são cinco meses na legenda e você declara 4 valores para o eixo y apenas) o gráfico fica desalinhado. Como faço caso eu queira simular descontinuidades nesse tipo de gráfico com sua biblioteca? (exemplo: digamos que seja um gráfico de vendas de concorrentes, e que em algum mês ou ano, um concorrente faliu mas os outros ativos (ou seja, com valores)).
Do mais, parábens.
@Leonardo,
Então, como essa é uma primeira versão eu não pensei em dados descontínuos, por isso deu esse problema que você relatou.
Já criei uma issue no repositório para não esquecer de corrigir esse problema. Mas, para esse caso das vendas, você pode passar entradas 0 para o concorrente que faliu a partir do dito mês. No entanto, para simular gaps no gráfico fica, nessa versão, impossível.
A solução que penso em implementar é permitir que o usuário passe valores None na sua lista, dessa forma, o script vai reconhecê-los e não desenhará a as linhas conectando esses estados. Posso até adicionar uma opção que permite ao usuário decidir se ele quer ou não que o script interpole (linearmente) as posições que estão faltando.
Muito obrigado pelo teste e pelas informações sobre os problemas, são essas informações que vão fazer a api crescer e prover mais funcionalidades para todos.
Sim, sobre a versão, realmente só funciona com o python 2.5 em face da sintaxe do if else de uma linha. Vou até colocar uma informação sobre isso na descrição do projeto no Google Code.
Abraços,
Shiny! Blurry! There seems to be quite a lot of graph APIs for python. It seems that everyone designs their own instead of reusing existing APIs (I’ve written like three!)
Rapaz, ficou muito massa!!!!
Sounds like a really cool library! Good job!
But, I do have one tiny problem with it. What if someone does not want to save the plot in a file, e.g. the plot is served (dynamically) by a web server? Can the filename be omitted?
http://matplotlib.sourceforge.net/screenshots.html
Parabéns!
Salvou o meu dia, estava me matando com o matplotlib para plotar graficos simples.
Muito Obrigado.
[...] CairoPlot - Plotting Graphics using Python and Cairo « (tags: graph charts) [...]
Hi,
does this library work on Windows too? Or alternatively, can you provide some info on using Cairo on Windows?
Thanks
According to Cairo’s official Documentation site, all you need to run it on Windows are:
cairo-1.4.8.zip
libpng 1.2.8
Zlib 1.2.3
all obtained at the official GTK+ for Windows page.
After that, you’ll need to install pyCairo on windows which I don’t know how to do yet. I’m, however, in touch with the guys over at pyCairo to understand whether or not it’s possible, so keep following as we’ll have a major release to CairoPlot within the next few days.
Thanks for the interest.
teste_data_2 = {”john” : [10, 10, 10, 10, 30], “mary” : [0, 0, 3, 5, 15], “philip” : [13, 32, 11, 25, 2]}
teste_h_legend = ["jan/2008", "feb/2008", "mar/2008", "apr/2008", "may/2008"]
CairoPlot.dot_line_plot(’Spam’, teste_data_2, 400, 300, axis = True, grid = True, h_legend = teste_h_legend)
Traceback (most recent call last):
File “./flexstats.py”, line 44, in
CairoPlot.dot_line_plot(’Spam’, teste_data_2, 400, 300, axis = True, grid = True, h_legend = teste_h_legend)
File “/home/thiagoc/workspace/flexstats/CairoPlot.py”, line 410, in dot_line_plot
plot.render()
File “/home/thiagoc/workspace/flexstats/CairoPlot.py”, line 316, in render
self.calc_horz_extents()
File “/home/thiagoc/workspace/flexstats/CairoPlot.py”, line 229, in calc_horz_extents
self.calc_extents(HORZ)
File “/home/thiagoc/workspace/flexstats/CairoPlot.py”, line 222, in calc_extents
self.max_value[direction] = self.context.text_extents(widest_word)[2]
TypeError: Context.text_extents() argument must be a string or unicode object
widest_word era uma lista, por isso estava dando erro.
Alterei desta forma e funcionou:
221 widest_word = max(self.labels[direction], lambda item: self.context.text_extents(item)[2])
222 self.max_value[direction] = self.context.text_extents(max(widest_word))[2]
Opa Thiago,
Valew aí o bug fix, vou corrigir na próxima versão.
Abs