Plot coordinate pairs: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|PureBasic}}: Added PureBasic)
m (→‎{{header|PureBasic}}: Correction of format)
Line 406: Line 406:
serie_y: Data.f 2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0
serie_y: Data.f 2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0
EndDataSection</lang>
EndDataSection</lang>
[[File:PureBasic PlotData.png|400px|thumb|left|PureBasic, Plot coordinate pairs]]
[[File:PureBasic PlotData.png|400px]]


=={{header|Python}}==
=={{header|Python}}==

Revision as of 17:51, 21 August 2010

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 * lx, floor(miny) - YLAB_HEIGHT_F * ly,

ceil(maxx) + EXTRA_W * lx, ceil(maxy) + EXTRA_H * 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 ( lx < ly ) {
   sx = lx/ly;
   sy = 1.0;
 } else {
   sx = 1.0;
   sy = ly/lx;
 }
 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 * 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.

gnuplot

Example gnuplot output

<lang gnuplot>unset key # Only one data set, so the key is uninformative

plot '-' # '-' can be replaced with a filename, to read data from that file.

 0   2.7
 1   2.8
 2  31.4
 3  38.1
 4  68.0
 5  76.2
 6 100.5
 7 130.0
 8 149.3
 9 180.0

e</lang>


F#

Using the F# for Visualization library:

alt text

<lang fsharp>#r @"C:\Program Files\FlyingFrog\FSharpForVisualization.dll"

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

open FlyingFrog.Graphics

Plot([Data(Seq.zip x y)], (0.0, 9.0))</lang>

Haskell

gnuplot is a package from HackageDB. <lang haskell>import Graphics.Gnuplot.Simple

pnts = [2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0]

doPlot = plotPathStyle [ ( Title "plotting dots" )]

           (PlotStyle Points (CustomStyle []))  (zip [0..] pnts)</lang>

HicEst

<lang HicEst>REAL :: n=10, x(n), y(n)

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)

WINDOW(WINdowhandle=wh, Width=-300, Height=-300, X=1, TItle='Rosetta') AXIS(WINdowhandle=wh, Title='x values', Yaxis, Title='y values') LINE(X=x, Y=y, SymbolDiameter=2)</lang>

J

Library: plot

<lang j>require 'plot' X=: i.10 Y=: 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 X;Y</lang> Output of plot.

Mathematica

<lang Mathematica>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}; ListPlot[{x, y} // Transpose]</lang> Output: [1]

MATLAB

<lang MATLAB>>> 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(x,y,'.-')</lang>

Maxima

<lang 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"])$</lang>

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>

Octave

<lang octave>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(x,y,"o"); pause;</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;

  1. Save as image.

$format = $graph->export_format; open(OUF, ">qsort-range-10-9.$format"); binmode OUF; print OUF $gd->$format(); 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>

PicoLisp

Example picoLisp output

<lang PicoLisp>(load "@lib/ps.l")

(scl 1)

(de plot (PsFile DX DY Lst)

  (let (SX (length Lst)  SY (apply max Lst)  N 0 Val)
     (out PsFile
        (psHead (+ DX 20) (+ DY 40))
        (font (9 . "Helvetica"))
        (if (or (=0 SX) (=0 SY))
           (window 60 12 DX DY
              (font 24 ,"Not enough Data") )
           (setq Lst  # Build coordinates
              (let X -1
                 (mapcar
                    '((Y)
                       (cons
                          (*/ (inc 'X) DX SX)
                          (- DY (*/ Y DY SY)) ) )
                    Lst ) ) )
           (color 55 95 55  # Background color
              (let (X (+ DX 40) Y (+ DY 40))
                 (poly T  0 0  X 0  X Y  0 Y  0 0) ) )
           (window 20 20 DX DY  # Plot coordinates
              (poly NIL 0 0  0 DY  (- DX 20) DY)
              (color 76 24 24
                 (poly NIL (caar Lst) (cdar Lst) (cdr Lst)) ) )
           (window 4 4 60 12 (ps (format SY *Scl)))
           (for X SX
              (window (+ 6 (*/ (dec X) DX SX)) (+ 24 DY) 30 12
                 (ps (format (dec X)) 0) ) ) )
        (page) ) ) )

(plot "plot.ps" 300 200 (2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0)) (call 'display "plot.ps")</lang>

PureBasic

<lang PureBasic>Structure PlotData

 x.i
 y.f

EndStructure

Global i, x, y.f, max_x, max_y, min_x=#MAXLONG, min_y=Infinity() Global count=(?serie_y-?serie_x)/SizeOf(Integer)-1 Global Dim MyData.PlotData(count)

Restore serie_x For i=0 To count

 Read.i x
 MyData(i)\x=x
 If x>max_x: max_x=x:  EndIf 
 If x<min_x: min_x=x:  EndIf

Next Restore serie_y For i=0 To count

 Read.f  y
 MyData(i)\y=y
 If y>max_y: max_y=y:  EndIf 
 If y<min_y: min_y=y:  EndIf  

Next

Procedure UpdatePlot(Win, w, h)

 If w>20 And h>20
   Protected x, y, i, yf.f, xf.f, img
   Protected x0=20, y0=h-20, amounts=ArraySize(MyData())
   Protected x1,x2,y1,y2
   yf=(h-20)/max_y*0.99
   xf=(w-20)/max_x*0.99
   CreateImage(0,w,h)
   Define OutputID=ImageOutput(0)
   StartDrawing(OutputID)
   DrawingMode(#PB_2DDrawing_Transparent)
   LineXY(20,h-20,w,h-20,$FFFFFF)
   LineXY(20,h-20,20,0,$FFFFFF)
   For i=0 To amounts
     ;- Draw grid
     x1=20: x2=w
     y1=(h-20)-max_y*i/amounts*yf
     y2=y1
     LineXY(x1,y1,x2,y2,$467E3E)
     ; Y-scale
     DrawText(1,y1-5,RSet(StrD(i/10*max_y,1),5))
     x1=20+max_x*i/amounts*xf
     x2=x1:  y1=(h-20):  y2=0
     ; X-Scale
     LineXY(x1,y1,x2,y2,$467E3E)
     If i: DrawText(x1-5,y1+2,Str(i)): EndIf
     ;- Draw curve
     x=20+MyData(i)\x*xf
     y=(h-20)-MyData(i)\y*yf
     LineXY(x0,y0,x,y,$0133EE)
     x0=x: y0=y
   Next
   StopDrawing()
   ImageGadget(0,0,0,w,h,ImageID(0))
 EndIf

EndProcedure

Define Flags=#PB_Window_SystemMenu|#PB_Window_SizeGadget Define Win=OpenWindow(#PB_Any,0,0,400,400,"PureBasic Plot",Flags) If Win

 SmartWindowRefresh(Win,1)
 UpdatePlot(Win, WindowWidth(Win), WindowHeight(win))
 Repeat
   Define Event =WaitWindowEvent()
   Select Event
     Case #PB_Event_SizeWindow
       UpdatePlot(Win, WindowWidth(Win), WindowHeight(win))
   EndSelect
 Until Event=#PB_Event_CloseWindow

EndIf

DataSection

 serie_x: Data.i 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
 serie_y: Data.f 2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0

EndDataSection</lang>

Python

Library: matplotlib
matplotlib plot of x,y arrays

<lang python>>>> 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')</lang> qsort-range-10-9.png (23 KiB)

R

R has several different plotting paradigms. First we define the data. <lang R>x <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) y <- c(2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0)</lang>

Base graphics

<lang R>plot(x,y)</lang>

Lattice/grid graphics

Library: lattice

<lang R>library(lattice) xyplot(y~x)</lang>

Grammar of graphics

Library: ggplot2

<lang R>library(ggplot2) qplot(x,y)</lang>

Tcl

Library: Tk
Library: Img

This solution does not use existing plotting packages, but constructs the graphics from bare-metal Tk code. <lang Tcl>package require Tk

  1. The actual plotting engine

proc plotxy {canvas xs ys} {

   global xfac yfac
   set maxx [tcl::mathfunc::max {*}$xs]
   set maxy [tcl::mathfunc::max {*}$ys]
   set xfac [expr {[winfo width $canvas] * 0.8/$maxx}]
   set yfac [expr {[winfo height $canvas] * 0.8/$maxy}]
   scale $canvas x 0 $maxx $xfac
   scale $canvas y 0 $maxy $yfac
   foreach x $xs y $ys {
       dot $canvas [expr {$x*$xfac}] [expr {$y*$yfac}] -fill red
   }

}

  1. Rescales the contents of the given canvas

proc scale {canvas direction from to fac} {

   set f [expr {$from*$fac}]
   set t [expr {$to*$fac}]
   switch -- $direction {
       x {
           set f [expr {$from * $fac}]
           set t [expr {$to * $fac}]
           $canvas create line $f 0 $t 0
           $canvas create text $f 0 -anchor nw -text $from
           $canvas create text $t 0 -anchor n -text $to
           
       }
       y {
           set f [expr {$from * -$fac}]
           set t [expr {$to * -$fac}]
           $canvas create line 0 $f 0 $t
           $canvas create text 0 $f -anchor se -text $from
           $canvas create text 0 $t -anchor e -text $to
       }
   }

}

  1. Helper to make points, which are otherwise not a native item type

proc dot {canvas x y args} {

   set id [$canvas create oval [expr {$x-3}] [expr {-$y-3}] \
               [expr {$x+3}] [expr {-$y+3}]]
   $canvas itemconfigure $id {*}$args

}

pack [canvas .c -background white] update set xs {0 1 2 3 4 5 6 7 8 9} set ys {2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0} plotxy .c $xs $ys .c config -scrollregion [.c bbox all] .c move all 20 20

  1. Save image (this is the only part that requires an external library)

package require Img set im [image create photo -data .c] $im write plotxy.png -format PNG</lang> Of course, if we were generating an encapsulated postscript version, we would be able to do that directly.

TI-89 BASIC

TI-89 screenshot

<lang ti89b>FnOff PlotsOff NewPlot 1, 1, x, y ZoomData</lang>

Ursala

Ursala doesn't plot anything directly, but has libraries to generate LaTeX code for 2D and 3D graphics. The output file has to be run through LaTeX or included into a LaTeX document. Here's the way to do it just as a quick check (all default settings and dots connected with straight lines). <lang Ursala>#import std

  1. import flo
  2. import fit
  3. import plo

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>

  1. output dot'tex' latex_document+ plot

main = visualization[curves: <curve[points: ~&p/x y]>]</lang> (output)

Here's one way you might do it if you were interested in publication quality graphics. The dots are connected with a cubic spline interpolating function sampled at 200 points, and the axes are nicely labeled.

<lang Ursala>main =

visualization[

  abscissa: axis[
     variable: 'problem size',
     hats: printf/*'%0.0f' ari10/0. 9.],
  ordinates: ~&iNC axis[
     variable: 'execution time ($\mu$s)',
     hats: printf/*'%0.1f' ari6/0. 180.],
  curves: <
     curve[
        points: ^(~&,chord_fit0@p/x y)* ari200/0. 9.,
        attributes: {'linecolor': 'lightgray'}],
     curve[
        scattered: true,
        points: ~&p/x y,
        attributes: {'linecolor': 'black'}]>]</lang>

(output)