Script para a geração de gráfico a partir de um arquivo csv

Iniciado por renan.taraborelli, 19 de Dezembro de 2008, 15:34

tópico anterior - próximo tópico

renan.taraborelli

Boa tarde pessoal.

Aqui na empresa tínhamos um arquivo de log de um servidor, no formato csv, onde cada linha representava um segundo de um teste que fizemos e cada "coluna" representava algum dado a respeito do servidor. Eu precisava fazer vários gráficos demonstrando os resultados conforme a evolução do teste.

No começo, utilizei a planilha eletrônica do OpenOffice. Abria o csv,  convertia, fazia uma coluna numerada, configurava o gráfico seeeempre da mesma maneira, gerava o gráfico, tirava o print screen da tela, cortava o gráfico no GIMP e salvava na pasta desejada.

Se fossem uns... dez, quinze gráficos não haveria problema, mas haviam vários gráficos, e alguns dias inteiros teriam que ser gastos simplesmente gerando gráficos e mais gráficos no OpenOffice. Haveria choro e ranger de dentes.

Então tive a idéia de usar algum programa linha de comando para automatizar esse processo. Eu precisaria de um programa em linha de comando pra gerar gráficos em formato jpeg ou png a partir de um arquivo csv. Existia o gnuplot, um programa gerador de gráficos. Agora eu precisava de um script.

Procurando na internet, um amigo me mostrou o inteligente csv2gnuplot: http://www.cs.waikato.ac.nz/~fracpete/programming/csv2gnuplot/

um shell script que deveria fazer o que eu precisava. Mas por alguma razão que não consegui descobrir, ele não exportava o gráfico pra um arquivo de imagem. Então decidi fazer meu próprio shell script com base nele, e "batizei" o script de "mohawk".

O código nos foi útil. E gostaria de compartilha-lo com vocês, caso alguém precise, ou queira melhorar. Sei que há imprecisões, e alguns erros de principiante, mas esse foi meu primeiro script, rs.

Abaixo, a descrição que coloquei na página da empresa seguida pelo script. Espero que seja útil.

Abraços!

renan.taraborelli

#1
Mohawk é um shell script escrito para gerar gráficos no formato png a partir de um ou mais arquivos csv.
Então o programa consulta uma "coluna" do arquivo csv dado e joga os dados em um gráfico. Cada linha corresponde a uma unidade no eixo x gerado.


Um exemplo de uso dele é esse:

./mohawk.sh -i 'teste-servidor.csv' -c 7  -o 'grafico.png' -r yes -t 'desempenho cpu' -y '% cpu'


Com essa sintaxe, o script
- dará um gráfico a partir da coluna 7 (-c 7) do csv teste-servidor.csv (parâmetro -i = INPUT)
- dará a esse gráfico o nome de grafico.png (parâmetro -o = OUTPUT)
- criaráo arquivo no mesmo diretório do arquivo csv. Parâmetro -r = RECURSIVO : yes/no. "no" faz o arquivo ser criado no diretório em que o mohawk foi executado.
- dará para o gráfico o título "desempenho cpu' (parâmetro -t), eixo y com a legenda "% cpu" (parâmetro -y)


Na verdade, o propósito dele é poder ser utilizado com vários arquivos, pois gerar apenas um gráfico usando o Excel é rápido. Gerar vários é muito trabalhoso.
O parâmetro -r (Recursivo) foi feito para que eu pudesse juntar vários comandos mohawk diferenciando entre eles apenas o nome do arquivo, e que deixasse os gráficos no mesmo diretório do arquivo csv.

Exemplo de uso do mohawk:

./mohawk.sh -t '% desempenho' -r yes -c 8 -o 'grafico.png' -i '/home/usuario/testes/teste12/banco/teste-servidor.csv'
./mohawk.sh -t '% desempenho' -r yes -c 8 -o 'grafico.png' -i '/home/usuario/testes/teste12/iptables/teste-servidor.csv'
./mohawk.sh -t '% desempenho' -r yes -c 8 -o 'grafico.png' -i '/home/usuario/testes/teste12/jms/teste-servidor.csv'
./mohawk.sh -t '% desempenho' -r yes -c 8 -o 'grafico.png' -i '/home/usuario/testes/teste12/pbx/teste-servidor.csv'

Sem o parâmetro -r, eu deveria adicionar todo o caminho do csv ao parâmetro -o. Seria um retrabalho inútil, principalmente se você imaginar que precisávamos gerar vários gráficos a partir de vários csvs e de várias colunas, em diretórios diferentes.

O código não está totalmente pronto. Ainda há o que fazer nele. Mas tirando suas limitações normais, só detectei um defeito nele. Quando você digita ./mohawk -h, para conseguir ajuda, o programa tenta continuar executando após exibir a mensagem de help. Como não são dados parâmetros, ele irá exibir algumas mensagens de erro após apresentar a sintaxe do programa, mas isso pode ser ignorado.

renan.taraborelli


#!/bin/bash
function usage()
{
echo "MOHAWK"
echo "Transforma um arquivo csv num grafico em imagem no formato png."
echo "Parâmetros:"
echo "-i <arquivo> Obrigatório"
echo " O arquivo csv que será utilizado."
echo " Deve estar sem os títulos das colunas, apenas os dados."
echo "-o <arquivo> "
echo " O arquivo PNG que será gerado."
echo " Deve conter a extensão .png"
echo "-r <yes/no>"
echo " Relativo. 'yes' fará o arquivo PNG ser criado na pasta do csv."
echo " Caso o parâmetro '-o' esteja omitido, essa opcão será automaticamente 'yes'."
echo "-t <título>"
echo " O título que estará acima do gráfico."
echo " Default: '$TITLE'"
echo "-c <coluna> Obrigatório"
echo " A coluna do arquivo CSV que será usada pra fazer o gráfico"
echo "-x <xlabel>"
echo " Nome da medida do eixo X."
echo " Default: '$XLABEL'"
echo "-y <ylabel>"
echo " Nome da medida do eixo Y."
echo " Default: '$YLABEL'"
echo
}
# variáveis
INPUT=""
OUTPUT=""
TITLE=""
RELATIVO="no"
COL="5"
HEIGHT="300"
WIDTH="400"
XLABEL="Tempo (minutos)"
YLABEL=""
# pega as variáveis
while getopts ":i:o:r:t:c:x:y:" flag
do
case $flag in
i) INPUT=$OPTARG;;
o) OUTPUT=$OPTARG;;
r) RELATIVO="$OPTARG";;
t) TITLE=$OPTARG;;
c) COL=$OPTARG;;
x) XLABEL=$OPTARG;;
y) YLABEL=$OPTARG;;
    h) usage exit 0;;
*) usage exit 0;;
esac
done
#
echo "$RELATIVO"
if [ "$RELATIVO" = "yes" ]
then
echo "$OUTPUT"
TEMPORARIA=`dirname "$INPUT"`
OUTPUT="${TEMPORARIA}/${OUTPUT}"
echo "$OUTPUT"
fi

#trata o arquivo csv puro
cut "$INPUT" -d ";" -f "$COL" > tmp
cat -n tmp > "$INPUT.tmp"
rm -f tmp

# propriedades comuns
echo "set terminal png size $WIDTH,$HEIGHT" > mohawk.tmp
echo "set grid y" >> mohawk.tmp
echo "set title '$TITLE'" >> mohawk.tmp
echo "set xlabel '$XLABEL'" >> mohawk.tmp
echo "set ylabel '$YLABEL'" >> mohawk.tmp
echo "set output '$OUTPUT'" >> mohawk.tmp
echo "plot '$INPUT.tmp' t'' with lines" >> mohawk.tmp
gnuplot mohawk.tmp


renan.taraborelli


RicardoSEP

Muito interessante essa solução de gerar o gráfico via Shell. Eu particularmente não sabia que isso era possível. A primeira solução que me veio a cabeça para fazer esses gráficos, seria fazer um programinha JAVA de linha de comando e utilizaria a biblioteca JFreeChart para criar os gráficos.

É mais uma solução, mas poderia ser qualquer linguagem (PHP, Pyhton, Ruby...) Basta ter uma biblioteca geradora de gráficos descente.

Abraço

renan.taraborelli

Sim, com certeza. Na verdade eu só tive a idéia de gerar gráficos via linha de comando quando vi que era possível via PHP, naqueles programas de monitoramento de servidor.

O gnuplot se mostrou bem interessante. Tem materiais muito bons sobre ele na net. Vale conferir uma referência sobre ele no Dept. de cartografia da UNESP de Presidente Prudente:

http://www2.fct.unesp.br/dcartog/galo/gnuplot/gnu_tutorial.htm

Para uma demonstração, após instalar, só digitar no terminal:


gnuplot

E dentro do gnuplot:

plot sin(x)

Darcamo

Uso o gnuplot e ele realmente é muito bom.
Você pode até mesmo fazer operações matemáticas nele.

Por exemplo, se tem um arquivo com quatro colunas você pode plotar a primeira (eixo X) pela soma das demais (fazendo assim o eixo Y), etc.
Pode plotar funções descontínuas, etc..