PLplot 02: O primeiro gráfico
A criação de gráficos utilizando a PLplot é bastante simples na maior parte do tempo. O conjunto de funções da biblioteca pode, a grosso modo, ser visto como dois conjuntos separados. Um conjunto de funções que definem as propriedades do gráfico — cor de fundo, tipo de linha, uso ou não de grades, escala, etc — e um conjunto de funções responsáveis pela plotagem do gráfico em si. Neste artigo, criaremos um gráfico básico com a PLplot.
Seja então f(x) a função que queremos plotar. Consideremos, a título de exemplo, f(x) como sendo definida por
O programa abaixo é uma implementação para que possamos gerar o gráfico dessa função. Praticamente nenhuma personalização é feita, deixando que a biblioteca utilize os parâmetros default para a maior parte das opções disponíveis.
O download do código-fonte pode ser feito aqui.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
/* exemplo01.c:
* Exemplo básico de uso da biblioteca PLPlot.
* Este programa simplesmente plota na tela o gráfico da função
*
* f(x) = x/(1 + x^2)
*
* praticamente nenhuma personalização é feita, deixando que a biblioteca
* utilize os parâmetros default.
*/
#include <plplot.h>
/* Número de pontos em que iremos calcular o valor de f(x) dentro do intervalo
* definido abaixo. Vamos utilizar um ponto adicional para ligar o último ponto
* calculado com outro calculado quando x = XMAX (definido abaixo). O número de
* pontos, ou melhor, o intervalo de amostragem que será utilizado dependerá de
* cada função. Fique esperto. */
#define NUMPONTOS 200
/* O intervalo em que a função será exibida. Isto quer dizer que teremos um
* ponto a cada intervalo dt, tal que dt = (XMAX - XMIN)/NUMPONTOS. Os limites
* para o eixo Y também estão definidos. */
#define XMIN -10
#define XMAX 10
#define YMIN -1.0
#define YMAX 1.0
/* A função função f(x). O tipo de dado PLFLT é, por padrão, uma variável do
* tipo float. Isso pode ser modificado definido uma variável de nome PL_DOUBLE
* ou somente DOUBLE utilizando a diretiva define do pré-processador. Isso deve
* ser feito antes de incluir a biblioteca no programa. No nosso caso, está
* perfeito do jeito que está, não precisamos alterar isso.
* A função abaixo recebe um valor x do tipo PLFLT como argumento e retorna o
* valor da função, tal como definimos na descrição desse programa. Esse
* procedimento é necessário porque a biblioteca não recebe uma função
* matemática como parâmetro e a plota, mas um conjunto de pontos que serão
* conectados entre si de alguma forma */
PLFLT f(PLFLT x)
{
return x/(1 + x*x);
}
int main (int argc, const char *argv[])
{
PLFLT x[NUMPONTOS + 1]; /* Vetor com os pontos do eixo x */
PLFLT y[NUMPONTOS + 1]; /* Vetor com os pontos do eixo y */
PLFLT dt; /* Intervalo de amostragem */
PLINT i;
/* Calcula o valor de f(x) em NUMPONTOS, com um intervalo de espaçamento dt
* e guardando esses valores nos vetores x e y para que possamos utilizá-los
* mais à frente */
dt = (PLFLT)(XMAX - XMIN)/NUMPONTOS;
for (i = 0; i < NUMPONTOS; i++) {
x[i] = XMIN + (PLFLT)i*dt;
y[i] = f(x[i]);
}
x[NUMPONTOS] = XMAX;
y[NUMPONTOS] = f(XMAX);
/* Inicializa PLplot. Essa função irá perguntar qual o dispositivo que
* você quer utilizar para plotar o gráfico. Se você deixar o campo em
* branco, a biblioteca irá selecionar o primeiro dispositivo na lista
* exibida */
plinit ();
/* Definindo limites do gráfico. A função plenv é responsável por criar a
* janela de exibição e desenhar uma caixa dentro dela, representando os
* eixos do nosso gráfico. Os limites do eixo x são definidos através de
* XMIN e XMAX. Os limites do eixo Y por YMIN e YMAX. O penúltimo diz
* respeito a escala do gráfico. O último parâmetro está associado as
* propriedades dos eixos e a caixa ao redor do gráfico. Iremos utilizar
* aqui o valor 1 para o penúltimo parâmetro, indicando que queremos que as
* escalas dos eixos x e y sejam as mesmas. Para o último, utilizamos o
* valor -1, indicando para o programa que desenhe apenas uma caixa ao redor
* do gráfico. Para maiores informações a respeito de valores que podem ser
* utilizados e o que cada um significa, leia a documentação da biblioteca
* presente no site oficial da mesma */
plenv (XMIN, XMAX, YMIN, YMAX, 0, -1);
/* Inserindo rótulos no gráfico. A função pllab permite a definição de
* rótulos no nosso gráfico. O primeiro argumento é rótulo do eixo x, o
* segundo é o rótulo do eixo y com algumas sequências de escape para
* podermos obter um sobrescrito como potência. O último é o título do
* gráfico. Dependendo do driver utilizado, pode não ser uma boa ideia o uso
* de acentos nas strings */
pllab ("x", "x/(1 + x#u2#d)", "Olá mundo dos gráficos!");
/* Plotando o gráfico. A função plline recebe três argumentos: o primeiro
* é o número de pontos que queremos plotar. O segundo é um vetor com as
* coordenadas do eixo x. O terceiro é um vetor com as coordenadas do eixo
* y. Essa função simplesmente desenha uma linha reta entre pontos
* consecutivos, assim como a maior parte dos softwares que plotam funções
* e exibem o resultado na tela. É ela a responsável por realmente desenhar
* o nosso gráfico */
plline (NUMPONTOS + 1, x, y);
/* Pronto, terminamos! A função plend é responsável por encerrar a PLplot,
* fazendo todos os ajustes necessários para que tudo ocorra como esperado e
* você tenha o seu gráfico ao final */
plend ();
return 0;
} |
Simples e rápido, não? Antes de compilarmos esse código, vamos dar uma olhada melhor nele. Note que qualquer programa que queira utilizar essa biblioteca deve adicionar o arquivo de cabeçalho plplot.h. É onde estão definidas todas as funções do quais iremos precisar para gerar os nossos gráficos.
Como foi dito no código, a PLplot não é capaz de receber uma expressão matemática como parâmetro e gerar um gráfico a partir disso, mas nada impede que você implemente uma função capaz de fazê-lo. Nesse caso, a biblioteca libmatheval seria de grande utilidade. Em artigos futuros, tentaremos implementar esse recurso.
Vamos compilar esse código e ver o que obtemos. Abra um terminal, navegue até o diretório onde colocou o programa e compile-o com o comando
|
1 |
$ gcc exemplo01.c `pkg-config --libs --cflags plplotd` -o exemplo01 |
Isso deverá gerar um executável de nome exemplo01 em seu diretório de trabalho. Vamos executá-lo:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
$ ./exemplo01
Plotting Options:
< 1> xwin X-Window (Xlib)
< 2> tk Tcl/TK Window
< 3> ps PostScript File (monochrome)
< 4> psc PostScript File (color)
< 5> xfig Fig file
< 6> null Null device
< 7> tkwin New tk driver
< 8> mem User-supplied memory device
< 9> wxwidgets wxWidgets Driver
<10> svg Scalable Vector Graphics (SVG 1.1)
<11> bmpqt Qt Windows bitmap driver
<12> jpgqt Qt jpg driver
<13> pngqt Qt png driver
<14> ppmqt Qt ppm driver
<15> tiffqt Qt tiff driver
<16> svgqt Qt SVG driver
<17> qtwidget Qt Widget
<18> epsqt Qt EPS driver
<19> pdfqt Qt PDF driver
<20> extqt External Qt driver
<21> memqt Memory Qt driver
<22> xcairo Cairo X Windows Driver
<23> pdfcairo Cairo PDF Driver
<24> pscairo Cairo PS Driver
<25> svgcairo Cairo SVG Driver
<26> pngcairo Cairo PNG Driver
<27> memcairo Cairo Memory Driver
<28> extcairo Cairo External Context Driver
Enter device number or keyword: |
Opa, mas o que diabos… Ah sim, o driver! Quando você executa o programa, a função plinit é chamada (linha 63). Ela verifica se um driver foi definido e em caso negativo, exibe a lista acima perguntando ao usuário qual utilizar. Note que temos várias opções. Se a opção escolhida for salvar o arquivo no disco, na forma de uma imagem (drivers ps, png, svg, pdfcairo, svgcairo, etc), o programa irá perguntar o nome da imagem que deverá ser utilizado e então salvar o arquivo nela. Mas vamos escolher a opção xcairo, número 22 na lista acima. Digite isso e dê um ENTER para visualizar o gráfico na tela:
Perfeito! Mas cadê as marcas nos eixos? Lembra que na linha 77, utilizamos a função plenv, onde o último parâmetro estava associado as propriedades dos eixos, bem como o desenho de uma caixa ao redor do gráfico? Pois é, fica como tarefa pra você: Leia a documentação dessa função no site oficial e veja quais são as outras opções possíveis. Modifique-as e recompile o seu programa para ver qual é o resultado. Teste também os diferentes drivers que podem ser utilizados e verifique quais são as diferenças entre eles.
No próximo artigo, iremos definir algumas propriedades do nosso gráfico como a cor de fundo, cor da linha utilizada para o gráfico, espessura, etc. Isso fará com que tenhamos algo mais personalizado.
Última atualização: 17/12/2012


