Plot coordinate pairs: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
(C)
Line 7: Line 7:


This task is intended as a subtask for [[Measure relative performance of sorting algorithms implementations]].
This task is intended as a subtask for [[Measure relative performance of sorting algorithms implementations]].

=={{header|C}}==

We could use the ''suite'' provided by [[:Category:Raster graphics operations|Raster graphics operations]], but those functions lack a facility to draw text.

{{libheader|libplot}}
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <plot.h>

#define NP 10
double x[NP] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
double y[NP] = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0};

void minmax(double *x, double *y,
double *minx, double *maxx,
double *miny, double *maxy, int n)
{
int i;

*minx = *maxx = x[0];
*miny = *maxy = y[0];
for(i=1; i < n; i++) {
if ( x[i] < *minx ) *minx = x[i];
if ( x[i] > *maxx ) *maxx = x[i];
if ( y[i] < *miny ) *miny = y[i];
if ( y[i] > *maxy ) *maxy = y[i];
}
}

/* likely we must play with this parameter to make the plot looks better
when using different set of data */
#define YLAB_HEIGHT_F 0.1
#define XLAB_WIDTH_F 0.2
#define XDIV (NP*1.0)
#define YDIV (NP*1.0)
#define EXTRA_W 0.01
#define EXTRA_H 0.01
#define DOTSCALE (1.0/150.0)

#define MAXLABLEN 32

#define PUSHSCALE(X,Y) pl_fscale((X),(Y))
#define POPSCALE(X,Y) pl_fscale(1.0/(X), 1.0/(Y))
#define FMOVESCALE(X,Y) pl_fmove((X)/sx, (Y)/sy)

int main()
{
int plotter, i;
double minx, miny, maxx, maxy;
double lx, ly;
double xticstep, yticstep, nx, ny;
double sx, sy;
char labs[MAXLABLEN+1];

plotter = pl_newpl("png", NULL, stdout, NULL);
if ( plotter < 0 ) exit(1);
pl_selectpl(plotter);
if ( pl_openpl() < 0 ) exit(1);

/* determines minx, miny, maxx, maxy */
minmax(x, y, &minx, &maxx, &miny, &maxy, NP);

lx = maxx - minx;
ly = maxy - miny;
pl_fspace(floor(minx) - XLAB_WIDTH_F * fabs(lx), floor(miny) - YLAB_HEIGHT_F * fabs(ly),
ceil(maxx) + EXTRA_W * fabs(lx), ceil(maxy) + EXTRA_H * fabs(ly));
/* compute x,y-ticstep */
xticstep = (ceil(maxx) - floor(minx)) / XDIV;
yticstep = (ceil(maxy) - floor(miny)) / YDIV;

pl_flinewidth(0.25);

/* compute scale factors to adjust aspect */
if ( fabs(lx) < fabs(ly) ) {
sx = fabs(lx)/fabs(ly);
sy = 1.0;
} else {
sx = 1.0;
sy = fabs(ly)/fabs(ly);
}

pl_erase();

/* a frame... */
pl_fbox(floor(minx), floor(miny),
ceil(maxx), ceil(maxy));

/* labels and "tics" */
pl_fontname("HersheySerif");
for(ny=floor(miny); ny < ceil(maxy); ny += yticstep) {
pl_fline(floor(minx), ny, ceil(maxx), ny);
snprintf(labs, MAXLABLEN, "%6.2lf", ny);
FMOVESCALE(floor(minx) - XLAB_WIDTH_F * fabs(lx), ny);
PUSHSCALE(sx,sy);
pl_label(labs);
POPSCALE(sx,sy);
}
for(nx=floor(minx); nx < ceil(maxx); nx += xticstep) {
pl_fline(nx, floor(miny), nx, ceil(maxy));
snprintf(labs, MAXLABLEN, "%6.2lf", nx);
FMOVESCALE(nx, floor(miny));
PUSHSCALE(sx,sy);
pl_ftextangle(-90);
pl_alabel('l', 'b', labs);
POPSCALE(sx,sy);
}

/* plot data "point" */
pl_fillcolorname("red");
pl_filltype(1);
for(i=0; i < NP; i++)
{
pl_fbox(x[i] - lx * DOTSCALE, y[i] - ly * DOTSCALE,
x[i] + lx * DOTSCALE, y[i] + ly * DOTSCALE);
}

pl_flushpl();
pl_closepl();
}</lang>

No one would use the previous code to produce a plot (that looks [http://i40.tinypic.com/f2t0l0.png this way]; instead, normally we produce data through a program, then we plot the data using e.g. gnuplot or other powerful tools; the result (with GNUplot and without enhancement) could look [http://i41.tinypic.com/2qivbsn.png like this] instead.

=={{header|J}}==
=={{header|J}}==
{{libheader|plot}}
{{libheader|plot}}

Revision as of 12:34, 3 March 2009

Task
Plot coordinate pairs
You are encouraged to solve this task according to the task description, using any language you may know.

Plot a function represented as `x', `y' numerical arrays.

Post link to your resulting image for input arrays (see Example section for Python language on Query Performance page):

x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
y = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0};

This task is intended as a subtask for Measure relative performance of sorting algorithms implementations.

C

We could use the suite provided by Raster graphics operations, but those functions lack a facility to draw text.

Library: libplot

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <math.h>
  3. include <plot.h>
  1. define NP 10

double x[NP] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; double y[NP] = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0};

void minmax(double *x, double *y, double *minx, double *maxx, double *miny, double *maxy, int n) {

 int i;
 *minx = *maxx = x[0];
 *miny = *maxy = y[0];
 for(i=1; i < n; i++) {
   if ( x[i] < *minx ) *minx = x[i];
   if ( x[i] > *maxx ) *maxx = x[i];
   if ( y[i] < *miny ) *miny = y[i];
   if ( y[i] > *maxy ) *maxy = y[i];
 }

}

/* likely we must play with this parameter to make the plot looks better

  when using different set of data */
  1. define YLAB_HEIGHT_F 0.1
  2. define XLAB_WIDTH_F 0.2
  3. define XDIV (NP*1.0)
  4. define YDIV (NP*1.0)
  5. define EXTRA_W 0.01
  6. define EXTRA_H 0.01
  7. define DOTSCALE (1.0/150.0)
  1. define MAXLABLEN 32
  1. define PUSHSCALE(X,Y) pl_fscale((X),(Y))
  2. define POPSCALE(X,Y) pl_fscale(1.0/(X), 1.0/(Y))
  3. define FMOVESCALE(X,Y) pl_fmove((X)/sx, (Y)/sy)

int main() {

 int plotter, i;
 double minx, miny, maxx, maxy;
 double lx, ly;
 double xticstep, yticstep, nx, ny;
 double sx, sy;
 
 char labs[MAXLABLEN+1];
 plotter = pl_newpl("png", NULL, stdout, NULL);
 if ( plotter < 0 ) exit(1);
 pl_selectpl(plotter);
 if ( pl_openpl() < 0 ) exit(1);
 /* determines minx, miny, maxx, maxy */
 minmax(x, y, &minx, &maxx, &miny, &maxy, NP);
 lx = maxx - minx;
 ly = maxy - miny;
 pl_fspace(floor(minx) - XLAB_WIDTH_F * fabs(lx), floor(miny) - YLAB_HEIGHT_F * fabs(ly),

ceil(maxx) + EXTRA_W * fabs(lx), ceil(maxy) + EXTRA_H * fabs(ly));

 /* compute x,y-ticstep */
 xticstep = (ceil(maxx) - floor(minx)) / XDIV;
 yticstep = (ceil(maxy) - floor(miny)) / YDIV;
 pl_flinewidth(0.25);
 /* compute scale factors to adjust aspect */
 if ( fabs(lx) < fabs(ly) ) {
   sx = fabs(lx)/fabs(ly);
   sy = 1.0;
 } else {
   sx = 1.0;
   sy = fabs(ly)/fabs(ly);
 }
 pl_erase();
 /* a frame... */
 pl_fbox(floor(minx), floor(miny),

ceil(maxx), ceil(maxy));

 /* labels and "tics" */
 pl_fontname("HersheySerif");
 for(ny=floor(miny); ny < ceil(maxy); ny += yticstep) {
   pl_fline(floor(minx), ny, ceil(maxx), ny);
   snprintf(labs, MAXLABLEN, "%6.2lf", ny);
   FMOVESCALE(floor(minx) - XLAB_WIDTH_F * fabs(lx), ny);
   PUSHSCALE(sx,sy);
   pl_label(labs);
   POPSCALE(sx,sy);
 }
 for(nx=floor(minx); nx < ceil(maxx); nx += xticstep) {
   pl_fline(nx, floor(miny), nx, ceil(maxy));
   snprintf(labs, MAXLABLEN, "%6.2lf", nx);
   FMOVESCALE(nx, floor(miny));
   PUSHSCALE(sx,sy);
   pl_ftextangle(-90);
   pl_alabel('l', 'b', labs);
   POPSCALE(sx,sy);
 }
 /* plot data "point" */
 pl_fillcolorname("red");
 pl_filltype(1);
 for(i=0; i < NP; i++)
 {
   pl_fbox(x[i] - lx * DOTSCALE, y[i] - ly * DOTSCALE,
           x[i] + lx * DOTSCALE, y[i] + ly * DOTSCALE);
 }
 pl_flushpl();
 pl_closepl();

}</lang>

No one would use the previous code to produce a plot (that looks this way; instead, normally we produce data through a program, then we plot the data using e.g. gnuplot or other powerful tools; the result (with GNUplot and without enhancement) could look like this instead.

J

Library: plot
   load 'plot'
   magnitudes =: 2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0
   'dot; pensize 2.4' plot magnitudes

Output of plot.

Maxima

(%i1) ".." (m, n) := makelist (i, i, m, n); infix ("..")$
(%i2) x: 0 .. 9$ y:[2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]$
(%i3) plot2d(['discrete, x, y], [style, [points,5,1,1]], [gnuplot_term, png], [gnuplot_out_file, "qsort-range-10-9.png"])$

qsort-range-10-9.png

OCaml

<lang ocaml>#load "graphics.cma" open Graphics

let round x = int_of_float (floor(x +. 0.5))

let x = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9] and y = [2.7; 2.8; 31.4; 38.1; 58.0; 76.2; 100.5; 130.0; 149.3; 180.0]

let () =

 open_graph "";
 List.iter2
   (fun x y ->
     (* scale to fit in the window *)
     let _x = x * 30
     and _y = round(y *. 2.0) in
     plot _x _y)
   x y;
 ignore(wait_next_event [Key_pressed]);
 close_graph();
</lang>

Perl

<lang perl>

use GD::Graph::points;

@data = (
  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
  [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0],
);
$graph = GD::Graph::points->new(400, 300);
$gd = $graph->plot(\@data) or die $graph->error;

# Save as image.
open(OUF, ">qsort-range-10-9.png");
binmode OUF;
print OUF $gd->png;
close(OUF);

</lang>

Library: Imager

<lang perl>

use Imager;
use Imager::Plot;

@x = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
@y = (2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0);
$plot = Imager::Plot->new(
  'Width' => 400,
  'Height' => 300,
  'GlobalFont' => 'PATH_TO_TTF_FONT',
);
$plot->AddDataSet(
  'X' => \@x,
  'Y' => \@y,
  'style' => {
    'marker' => {
      'size' => 2,
      'symbol' => 'circle',
      'color' => Imager::Color->new('red'),
    },
  },
);
$img = Imager->new(
  'xsize' => 500,
  'ysize' => 400,
);
$img->box('filled' => 1, 'color' => 'white');
$plot->Render('Image' => $img, 'Xoff' => 50, 'Yoff' => 350);
$img->write('file' => 'qsort-range-10-9.png');

</lang>

Python

Library: matplotlib
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]
>>> import pylab
>>> pylab.plot(x, y, 'bo')
>>> pylab.savefig('qsort-range-10-9.png')

qsort-range-10-9.png (23 KiB)