The graphics library grafxlib.py

The graphics library graphlib.py, put forward in the book was renamed grafxlib.py to avoid confusions with a recent standard module of Python. grafxlib.py is used throughout to produce runtime graphics both from Python and C/C++. The C/C++ applications access grafxlib.py via the interface grafxlib.h.

grafxlib.py Graphics library for Python based on Tkinter.
grafxlib.h Graphics library for C/C++ (contains C++ interface classes for grafxlib.py).

Sample plots

Simple example--plotting a function of one variable: P03-Plot.py (Python) and P03-Plot.cpp (C/C++).

To see all graphics applications, go to section PROGRAMS.

Structure of grafxlib.py

#--------------------------------- grafxlib.py ---------------------------------
# Graphics library based on Tkinter
# Copyright: Titus Beu, 2014-2021
#-------------------------------------------------------------------------------
from math import *
from utils import *
from tkinter import *

def MainLoop():                                       # creates Tk event loop
def GraphUpdate():                                   # updates Tk root widget
def GraphInit(nxwin, nywin):       # creates Canvas widget and returns object
def GraphClear():                          # deletes content of Canvas widget
#============================================================================
def Limits(xmin, xmax, maxint = 10):
#----------------------------------------------------------------------------
# Replaces the limits xmin and xmax of a real interval with the limits of
# the smallest extended inteval that includes a number <= maxint of
# subintervals of length d * 10**p, with d = 1, 2, 5 and p integer.
#
# scale - scale factor (10**p)
# nsigd - relevant number of significant digits
# nintv - number of subintervals
#
# Returns: xmin, xmax, scale, nsigd, nintv
#============================================================================
def FormStr(x, scale, nsigd):
#----------------------------------------------------------------------------
# Formats the number x (with factor scale) to nsigd significant digits
# returning the mantissa in mant[] and the exponent of 10 in expn[].
#
# Returns: mant, expn
#============================================================================
def Plot(x, y, n, col = "blue", sty = 1,
         fxmin = 0.15, fxmax = 0.95, fymin = 0.15, fymax = 0.90,
         xtext = "x", ytext = "y", title = None):
#----------------------------------------------------------------------------
# Plots a real function of one variable specified by a set of (x, y) points.
# The x and y-domains are extended to fit at most 10 intervals expressible
# as d * 10^p, with d = 1, 2, 5 and p integer.
#
# x[]   - abscissas of tabulation points (x[1] through x[n])
# y[]   - ordinates of tabulation points (y[1] through y[n])
# n     - number of tabulation points
# col   - plot color ("red", "green", "blue" etc.)
# sty   - plot style: 0 - scatter plot, 1 - line plot, 2 - polar plot,
#         3 - drop lines, 4 - histogram
# fxmin - min fractional x-limit of viewport (0 < fxmin < fxmax < 1)
# fxmax - max fractional x-limit of viewport
# fymin - min fractional y-limit of viewport (0 < fymin < fymax < 1)
# fymax - max fractional y-limit of viewport
# xtext - x-axis title; xtext == "None" - axis is not labeled
# ytext - y-axis title; ytext == "None" - axis is not labeled
# title - plot title
#============================================================================
def MultiPlot(x, y, sig, nend, col, sty, nplot, maxint = 10,
              xminp = 0.0, xmaxp = 0.0, ioptx = 0,
              yminp = 0.0, ymaxp = 0.0, iopty = 0,
              fxmin = 0.15, fxmax = 0.95, fymin = 0.15, fymax = 0.90,
              xtext = "x", ytext = "y", title = None):
#----------------------------------------------------------------------------
# Plots nplot real functions of one variable given by sets of (x,y) points.
# The coordinate sets are stored contiguously in the arrays x[] and y[].
# The x and y-domains are extended to fit at most maxint intervals
# expressible as d * 10^p, with d = 1, 2, 5 and p integer.
#
# x[]    - abscissas of tabulation points for all functions
# y[]    - ordinates of tabulation points
# sig[]  - error bars of the tabulation points (useful for sty == 4)
# nend[] - ending index for the individual plots (nmax = nend[nplot])
# col[]  - plot color ("red", "green", "blue" etc.)
# sty[]  - plot style 0 - scatter plot with squares
#                     1 - line plot; -1 - dashed line
#                     2 - polar plot; -2 - dashed line
#                     3 - drop lines
#                     4 - error bars; -4 - including line plot
# nplot - number of plots
# maxint - max. number of labeling intervals
# ioptx - 0 - resize x-axis automatically
#         1 - resize x-axis based on user interval [xminp, xmaxp]
# iopty - 0 - resize y-axis automatically
#         1 - resize y-axis based on user interval [yminp, ymaxp]
# fxmin - min fractional x-limit of viewport (0 < fxmin < fxmax < 1)
# fxmax - max fractional x-limit of viewport
# fymin - min fractional y-limit of viewport (0 < fymin < fymax < 1)
# fymax - max fractional y-limit of viewport
# xtext - x-axis title; xtext == "None" - axis is not labeled
# ytext - y-axis title; ytext == "None" - axis is not labeled
# title - plot title
#============================================================================
def RGBcolors(ncolstep):
#----------------------------------------------------------------------------
# Generates ncol = 1280/ncolsep RGB colors in icol[1] through icol[ncol]
#
# Returns: icol, ncol
#============================================================================
def ColorLegend(fmin, fmax, ixmin, ixmax, iymin, iymax):
#----------------------------------------------------------------------------
# Draws and labels the color legend for the interval [fmin,fmax] in the
# rectangle [ixmin,ixmax] x [iymin,iymax]. [fmin,fmax] is extended to fit at
# most 10 intervals expressible as d * 10^p, with d = 1, 2, 5 and p integer.
#
# Returns: fmin, fmax, icol, ncol, nintv
#============================================================================
def Contour(z, nx, ny, xmin, xmax, ymin, ymax, zmin, zmax,
            fxmin = 0.15, fxmax = 0.85, fymin = 0.15, fymax = 0.85,
            xtext = "x", ytext = "y", title = None):
#----------------------------------------------------------------------------
# Plots a function z(x,y) defined in [xmin,xmax] x [ymin,ymax] and tabulated
# on a regular Cartesian grid with (nx-1)x(ny-1) mesh cells as contour plot.
# The level curves result by inverse linear interpolation inside the cells.
#
# z     - tabulated function values
# nx    - number of x-mesh points
# ny    - number of y-mesh points
# zmin  - minimum level considered
# zmin  - maximum level considered
# fxmin - min fractional x-limit of viewport (0 < fxmin < fxmax < 1)
# fxmax - max fractional x-limit of viewport
# fymin - min fractional y-limit of viewport (0 < fymin < fymax < 1)
# fymax - max fractional y-limit of viewport
# xtext - x-axis title; xtext == "None" - axis is not labeled
# ytext - y-axis title; ytext == "None" - axis is not labeled
# title - plot title
#============================================================================
def PlotParticles(x, y, z, r, col, n, dmax,
                  xminp = 0.0, xmaxp = 0.0, ioptx = 0,
                  yminp = 0.0, ymaxp = 0.0, iopty = 0,
                  fxmin = 0.15, fxmax = 0.85, fymin = 0.15, fymax = 0.85,
                  xtext = "x", ytext = "y", title = None):
#----------------------------------------------------------------------------
# Plots a system of particles as connected colored spheres
#
# x,y,z[] - coordinates of particles
# r[]     - radii of particles
# col[]   - colors of particles ("red", "green", "blue" etc.)
# n       - number of particles
# dmax    - max inter-distance for which particles are connected
# ioptx - 0 - resize x-axis automatically
#         1 - resize x-axis based on user interval [xminp, xmaxp]
# iopty - 0 - resize y-axis automatically
#         1 - resize y-axis based on user interval [yminp, ymaxp]
# fxmin - min fractional x-limit of viewport (0 < fxmin < fxmax < 1)
# fxmax - max fractional x-limit of viewport
# fymin - min fractional y-limit of viewport (0 < fymin < fymax < 1)
# fymax - max fractional y-limit of viewport
# xtext - x-axis title; xtext == "None" - axis is not labeled
# ytext - y-axis title; ytext == "None" - axis is not labeled
# title - plot title
#============================================================================
def PlotStruct(x, y, z, n, ind1, ind2, ind3, n3,
               xminp = 0.0, xmaxp = 0.0, ioptx = 0,
               yminp = 0.0, ymaxp = 0.0, iopty = 0,
               fxmin = 0.15, fxmax = 0.85, fymin = 0.15, fymax = 0.85,
               xtext = "x", ytext = "y", title = None):
#----------------------------------------------------------------------------
# Renders a 3D structure defined by nodes and triangular surfaces
#
# x,y,z[] - coordinates of nodes
# n       - number of nodes
# ind1[]  - index of 1st node of each triangle
# ind2[]  - index of 2nd node of each triangle
# ind3[]  - index of 3rd node of each triangle
# n3      - number of triangles
# ioptx - 0 - resize x-axis automatically
#         1 - resize x-axis based on user interval [xminp, xmaxp]
# iopty - 0 - resize y-axis automatically
#         1 - resize y-axis based on user interval [yminp, ymaxp]
# fxmin - min fractional x-limit of viewport (0 < fxmin < fxmax < 1)
# fxmax - max fractional x-limit of viewport
# fymin - min fractional y-limit of viewport (0 < fymin < fymax < 1)
# fymax - max fractional y-limit of viewport
# xtext - x-axis title; xtext == "None" - axis is not labeled
# ytext - y-axis title; ytext == "None" - axis is not labeled
# title - plot title

Auxiliary functions

Limits extends an arbitrary real interval so as to include an integer number of equal subintervals of length expressible as d x 10p, with d = 2, 5, or 10 and p integer. Output: xmin and xmax--adjusted values of, scale--scale factor (10p), nsigd--number of significant digits required to optimally represent the limits, nintv--resulting integer number of subintervals. Limits is typically called by Plot and MultiPlot to adjust the x and y user intervals for optimal labeling of the axes, by Contour to resize contour plots, and by ColorLegend to resize color legends.

FormStr determines the optimal labeling format for a given value x on the basis of previous output from Limits (scale factor scale and number of significant digits nsigd), and separates the mantissa in mant[] and the exponent of 10 in expn[].

ColorLegend and RGBcolors are used to display a color legend alongside a contour plot.

Routines for plotting functions

Plot plots a real function of one variable. The arrays x[] and y[] should contain the coordinates pairs of the representative points. The plot color is specified by the parameter col, and the corresponding arguments can be RGB colors or standard color names. The plot-style parameter sty can take one of the integer values: 0--scatter plot, 1--line plot, 2--polar plot, 3--drop lines, 4--histogram. fxmin, fxmax, fymin, fymax are the fractional limits of the plotting domain on the canvas. xtext, ytext, and title are the titles of the axes and of the whole graph. "None" as axis title inhibits the labeling of the axis altogether. The independent coordinate x[] is not supposed to vary monotonically, and this also enables the representation of cyclic functions.

MultiPlot plots several functions of one variable on a single graph. The representative points of the nplot plots are contiguously packed in sequenced sets in the same vectors x[] and y[], with an additional array, n[], specifying the ending index for each set. sig[] is only used when error bars (sty[i]=4) are employed for at least one of the plots. col[] contains the colors of the individual plots and sty[] specifies the corresponding style parameters: 0--scatter plot, 1--line plot, -1--line plot with dashed line, 2--polar plot, -2--polar plot with dashed line, 3--drop lines, 4--error bars, -4--error bars and continuous line. For ioptx set to 0, the x-axis is resized automatically, while for nonzero ioptx, the axis is resized based on the provided user interval [xminp,xmaxp]. The y-axis is resized analogously, in accordance with the option iopty.

Contour creates the contour plot of a real function of two variables, defined in the domain [xmin,xmax] x [ymin,ymax] and specified by its values z[i][j] at the nx x ny nodes of a regular grid. The representation is confined to z-values between zmin and zmax.

Simple 3D rendering routines

PlotParticles depicts systems of particles as spheres, optionally connected by cylindrical bonds. The input consists of the coordinate vectors x[], y[], and z[] of the centers of the n particles, their radii r[], and colors col[]. dmax is a cutoff distance beyond which the particles are no longer linked by bonds (with dmax set to 0, no bonds at all are depicted). The ioptx and iopty parameters control whether the x and y-axis, respectively, are to be sized automatically in order to reveal the entire structure (ioptx=0 and iopty=0), or, instead, the input user coordinates (xminp,xmaxp) and (yminp,ymaxp) are to be considered to crop the image.

PlotStruct is a simple 3D rendering routine for structures specified by nodes and triangular surfaces defined between them. The input to PlotStruct consists of the coordinate vectors x[], y[], and z[] of the n nodes and the indexes ind1[], ind2[], and ind3[] of the nodes defining each of the n3 triangles.

Histograms

Histograms can be plotted using Plot with the style parameter sty=4. Before plotting a histogram, the data need to be binned. HistoBin is normally operated in three successive modes:

  1. Initializing the histogram--defining the boundaries of the bins and zeroing the corresponding frequencies.
  2. Binning new observations--assigning them to the appropriate bins and incrementing the corresponding occurrence frequencies.
  3. Normalizing the histogram--dividing the frequencies by the total number of observations.

The input parameters are xnew--new value to be binned, a and b--limits of the total binning interval (data falling outside are ignored), n--number of bin boundaries (n-1 is the number of bins), and iopt--option specifying the mode in which the routine is to be used: 0--to initialize the histogram, 1--to bin the new value xnew, and 2--to normalize the histogram. The output consists of the vectors x[], containing the bin boundaries, and y[], representing the (normalized or unnormalized) frequencies. Specifically, y[i] is the frequency of observations occurring in the interval [x[i],x[i+1]).

Creating plots in C++ using the library grafxlib.py

The C++ programs including the interface file grafxlib.h can seamlessly call with similar syntax the Python graphics functions defined in the module grafxlib.py/span>. The proper functioning of grafxlib.h requires access to grafxlib.py (and to the therein imported module utils.py)) either by search path settings or by simply placing the three files in the same folder.