SkillAgentSearch skills...

Qplplot

q bindings of plplot -- 100M data points histogrammed in 500ms.

Install / Use

/learn @jaeheum/Qplplot
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Qplplot

Q bindings of PLplot graphical data plotting library.

PLplot provides C API to plot data. Qplplot is q bindings of PLplot for plotting data both in interactive mode inside kdb+ sessions and in batch mode from *.q scripts.

A notable feature of PLplot is its speed. For example, plhist() computes distribution or frequency of a data array of 100 million elements and makes a histogram plot in a window in subsecond on a modern laptop. (Sandy Bridge i7 from 2012 takes about 600ms). There is no copying or transfering data from q to PLplot as qplplot passes a pointer so that plotting is done with in-place data managed by kdb+. Compare running example scripts x05.q and x05w100M.q.

version

As of today (2015.02.16), qplplot supports most of PLplot 5.10, the latest public release.

Qplplot Documentation

PLplot documentation

qplplot synopsis

Qplplot (in qplplot.q) uses pl as its namespace prefix.

\l qplplot.q / loads qplplot API as a dictionary named pl.
pl.functionname[] / matches plfunctionname() (functionname is a placeholder name)
pl`OPTION / matches OPTION C symbol exported by plplot.h

PLplot vs qplplot

Qplplot API mirrors that of PLplot so that users can refer to PLplot API reference.

pl.functionname[] corresponds to plfunctionanme() in PLplot. For example,

PLplot in C             qplplot
-----------------------------------------------
plinit()                pl.init[]
plline(n, x, y)         pl.line[n; x; y]

Translating API of PLplot to q or qplplot is easy once types are understood:

PLplot types            q types
-----------------------------------------------
(PLINT, input)          `int atom or type -6h
(PLFLT, input)          `float atom or type -9h
(PLBOOL, input)         `int atom or type -9h, (NOT `boolean or -1h)
(const PLFLT *, input)  `float vector or 9h
(char *, input)         `sym or -11h
(char *, output)        `sym or -11h, N.B. output parameter

Therefore plline(PLINT n, const PLFLT* x, const PLFLT* y) would be translated into q as pl.line[n; x; y] where n:count x; x and y, vectors of float (of equal counts).

Here is a short example that draws a random walk across 1000 points:

\l qplplot.q
pl.init[] / plinit();
pl.env[0f;1f;0f;1f;0;0] / plenv(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLINT just, PLINT axis).
pl.col0 9 / plcol0(PLINT icol0); // same as pl.col0 pl`blue;
K:1000
x:K?1f
y:K?1f
pl.line[K;x;y] / plline(PLINT n, const PLFLT*, const PLFLT* y); // draw lines of random walk across 1000 points.
pl.lab[`x; `y; `$"random walk across 1000 points"]
/ pllab(const char* xlabel, const char* ylabel, const char* tlabel);
pl.end[] / plend();
\\

Many PLplot APIs use PLplot's exported C symbols or constants. For example, plmesh() expects a PLINT opt argument that can be either DRAW_LINEX, DRAW_LINEY, or DRAW_LINEXY. In qplplot's pl.mesh[], these opt values are q symbol keys to pl: pl`DRAW_LINEX, pl`DRAW_LINEY or pl`DRAW_LINEXY.

plcol0() expects an integer argument representing a color. Qplplot lets users to use color names listed in the plcol0 reference, e.g. pl.col0[0] works as well as pl.col0[pl`black].

Most PLplot APIs return void but some return an output parameter (marked output type). For example, plgver()

plgver(char* p_ver);
    p_ver (char *, output)
           Pointer to the current library version number.

Qplplot's counterpart returns output parameter p_ver as a symbol:

q)pl.gver[]
`5.10.0

Some other APIs return multiple output parameters and qplplot wraps them in a dictionary. For example, plgchr()

q)pl.gchr[] / plgchr(&p_def, &p_ht); in C
p_def| 7.5
p_ht | 7.5

Notice that symbol keys of the output dictionary match the names of output parameters in PLplot's API reference.

further hints for translation

  • A qplplot function name is same as PLplot's original name except for a . between pl and the rest of the name.
  • Most PLplot API names are abbreviations:
    • plg*() APIs are usually getter functions, e.g. plgver() or pl.gver[] above.
    • pls*() APIs are usually setter functions, e.g. plsdev(const char* devname) or pl.sdev[`devname].
  • Examples resemble PLplot's original examples closely. See Examples section below.

types or `int vs `long

  • PLINT atom can be passed as `long or -7h as long as its value fits `int. This leniency lets users skip adding i-suffix behind every integer that is `long by default in Kdb+ 3.0 or later.
  • However, if a list that expects a PLINT (or PLBOOL), make sure to use `int in q.
  • Getters (plg*() or pl.g*[]) returning PLINT returns `int (see x31.q).

special cases

Because a q function allows maximum of 8 arguments (define a function with more than 8 arguments and q returns 'params exception), some PLplot APIs with more than 8 arguments deserve special attention.

For most PLplot APIs, qplplot preserves order, count and types of arguments of the original PLplot APIs so that PLplot's API documentation can cover qplplot's. However, PLplot APIs with more than 8 arguments are expressed differently in qplplot:

  • Arguments are grouped logically into lists. See the pl.* functions below and cross-check with PLplot's reference.

  • Often, argument for count and other bookkeeping arguments are elided.

  • plcont() uses a callback function: a user-defined one as well as built-in pltr0, pltr1 or, pltr2. Qplplot's pl.cont* come with four flavors: pl.cont[], pl.cont0[], pl.cont1[] and pl.cont2[]. See examples for usage (see Examples section below).

  • Likewise for plimagefr(), plshade(), plshades(), plvect().

  • See also Bugs section below.

      pl.box3[(`xopt;`lsxlabel;xtick;nxsub);
          (`yopt;`lsylabel;ytick;nysub);
          (`zopt;`lszlabel;ztick;nzsub)]
      pl.colorbar[dict] / dict is made of all input args as keys and values.
          / Returns a dict with keys p_colorbar_width and p_colorbar_height.
      pl.cont[z; (kx;lx); (ky;ly); clevel; pltr; pltr_data]; / nlevel=count clevel
      pl.cont0[f; (kx;ly); (ky;ly); clevel]; / nlevel=count clevel; pltr0 called by qplplot.
      pl.cont1[z; (kx;ly); (ky;ly); clevel; xg1; yg1]; / nlevel=count clevel; pltr1 called by qplplot.
      pl.cont2[f; (kx;ly); (ky;ly); clevel; xg2; yg2]; / nlevel=count clevel; pltr2 called by qplplot.
      pl.imagefr[x; (xmin;xmax;ymin;ymax);(zmin;zmax);(valuemin;valuemax); pltr; pltr_data]
      pl.imagefr0[x; (xmin;xmax;ymin;ymax);(zmin;zmax);(valuemin;valuemax)]
      pl.imagefr1[x; (xmin;xmax;ymin;ymax);(zmin;zmax);(valuemin;valuemax); xg1; yg1]
      pl.imagefr2[x; (xmin;xmax;ymin;ymax);(zmin;zmax);(valuemin;valuemax); xg2; yg2]
      pl.image[x; (xmin;xmax; ymin;ymax);(zmin;zmax);(dxmin;dxmax;dymin;dymax)]
      pl.legend[(opt; position; x; y; plot_width);
          (bg_color; bb_color; bb_style);
          (nrow,ncolumn,nlegend);
          opt_array;
          (text_offset; text_scale;  text_spacing;  test_justification; text_colors; text);
          (box_colors; box_patterns; box_scales; box_line_widths);
          (line_colors; line_styles; line_widths);
          (symbol_colors; symbol_scales; symbol_numbers; symbols)]
      pl.ptex3[(x;y;z);(dx;dy;dz);(sx;sy;sz);just;text]
      pl.shade[a; defined;
          (xmin;xmax;ymin;ymax;shade_min;shade_max);
          (sh_cmap;sh_color;sh_width;min_color;min_width;min_color;max_color;max_width);
          fill; rectangular; pltr; pltr_data]
          / fill is ignored but left for future compatibility
      pl.shade1[a; defined;
          (xmin;xmax;ymin;ymax;shade_min;shade_max);
          (sh_cmap;sh_color;sh_width;min_color;min_width;min_color;max_color;max_width);
          fill; rectangular; pltr; pltr_data]
          / fill is ignored but left for future compatibility
      pl.shades[a; defined;
          (xmin; xmax; ymin; ymax; clevel);
          (fill_width; cont_color; cont_width);
          fill; rectangular; pltr]
          / fill is ignored but left for future compatibility
      pl.shades0[a; defined;
          (xmin; xmax; ymin; ymax; clevel);
          (fill_width; cont_color; cont_width);
          fill; rectangular] / pltr0 setby pl.shades0[]
      pl.shades2[a; defined;
          (xmin; xmax; ymin; ymax; clevel);
          (fill_width; cont_color; cont_width);
          fill; rectangular; xg2; yg2] / pltr2 setby pl.shades2[]
      pl.stripc[(xspec;yspec);
          (xmin;xmax;xjump; ymin;ymax);
          (xlpos;ylpos); (y_ascl;acc); (colbox;collab); (colline;styline;legline); (labx;laby;labtop)]
      pl.surf3d[x; y; z; opt; clevel]
      pl.surf3dl[x; y; z; opt; clevel; (xmin;xmax); ymin;ymax)]
      pl.fsurf3d[x; y; z; opt; clevel]
      pl.vect[u; v; scale; pltr]; / nx=count u; ny=count v;
      pl.vect0[u; v; scale]; / nx=count u; ny=count v; pltr0 set by plvect.
      pl.vect1[u; v; scale; xg1; yg1]; / nx=count u; ny=count v
    
View on GitHub
GitHub Stars14
CategoryDevelopment
Updated7mo ago
Forks4

Languages

C

Security Score

67/100

Audited on Aug 27, 2025

No findings