FE 'tkGooie' Utilities

'PLOTtools' group

'PlotQuik'
Lines (or Points)

from a MATH EXPRESSION
f(x) entered
on the GUI

(FE = Freedom Environment)

The FE 'PlotQuik' Points-or-Lines
MATH EXPRESSION Plot 'tkGooie'

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'PLOTtools' Page >

This PlotQuik lines-or-points from math expression Page

INTRODUCTION to the
'tkPlotQuik_LinesPoints_mathExpr_YatX' 'tkGooie'

On a page about a 'PlotQuik' utility nicknamed PlotQuik_PointsLines_XYdataEntry I explained that I am in the process of creating 5 'PlotQuik' utilities:

  1. for making pie charts from data entered in an entry field on a GUI

  2. for making xy-plots from xy-data entered in 2 entry fields on a GUI

  3. for making xy-plots from a math expression entered in an entry field on a GUI

  4. for making bar charts from data entered in 2 entry fields on a GUI

  5. for making xy-plots, created by selecting 2 or 3 columns of data from a text file containing columns of data

These utilities are intended for the 'PLOTtools' toolchest of an FE menu (or 'toolchest') system called 'tkGooies'.

The 'PlotQuik' page mentioned above (link above) explains the background of these utilities --- which involves FE (Freedom Environment) Tcl-Tk programming in the the 2011 to 2017 time frame.

In short, 'PlotQuik' utilities 1 and 2 were published on this FE web site at a PlotQuik Pie Chart page (in 2012) and at a PlotQuik Points(and Lines) from XY Data Entry page (in 2017).

This page presents the code for the 3rd 'PlotQuik' utility listed above -- the 'PlotQuik' utility for making xy-plots from a math expression entered in an entry field on the GUI.

A description of that code (and the GUI that it produces) follows.


THE GUI DESIGN

Following a Tk GUI design procedure that I started using around 2015, I make a 'text-sketch' of the layout of the GUI --- to help plan how the GUI will be implemented.

I used the following conventions to make the sketch, with a text editor.



  SQUARE BRACKETS indicate a comment (not to be placed on the GUI).
  BRACES          indicate a Tk 'button' widget.
  A COLON         indicates that the text before the colon is on a 'label' widget.
  UNDERSCORES     indicate a Tk 'entry' widget.

  CAPITAL-X       indicates a Tk 'checkbutton' widget.
  <----O---->     indicates a horizontal Tk 'scale' widget.
  CAPITAL-O       indicates a Tk 'radiobutton' widget (if any).


The options available to the user are indicated by the following 'sketch' of the GUI:



 FRAMEnames
 VVVVVVVVVV

 FRAMEnames
 VVVVVVVVVV
                   -----------------------------------------------------------------------------------
                   tkPlotQuik - XY Data from an Algebraic Expression
                   [window title]
                   -----------------------------------------------------------------------------------

 .fRbuttons        {Exit}{Help} X Points X Border {CanvasColor}{UpdatePlot}{GetImg}{DwnCan}{UpCan}{PrtPreview}{Print} [entry field for
                                                                                                                       a print command]
 .fRtitle_main     PlotTitle:_____________________________________________________________________________________________________

 .fRtitles_xy      XaxisTitle:__________________________________________ YaxisTitle: _____________________________________________

 .fRlims_xy        XaxisMin:__________ XaxisMax:__________ XticDist:_____ YaxisMin: __________ YaxisMax: __________ YticDist:_____

 .fRexpr           Expression: ___________________________________________________________________________________________________
                                                   2                                                                          1000
 .fRexpr_opts      Number of X vals to generate:  <---------------------------------O--------------------------------------------> 

 .fRlow            .fRlow.fRmsg                                   .fRlow.fRplot
                   [ an area here contains a brief                [ an area here
                     guide in a text or label widget                contains a canvas widget  
                     ...                                            ...
                     many                                           to be populated with
                     ...                                            ...
                     lines                                          'items' whenever the 'UpdatePlot' button
                     ...                                            ...
                     deep.                                          in frame 'fRbuttons' is poked.
                   ]                                              ]


GUI components:

From the GUI 'sketch' above, it is seen that the GUI consists of about

  • 9 button widgets
  • 11 label widgets
  • 10 entry widgets
  • 1 text widget (with scroll bars someday?)
    (or one more label instead)
  • 1 canvas widget (with scroll bars someday?)
  • 2 checkbutton widgets
  • 1 scale widget
  • 0 radiobutton widgets
  • 0 listbox widgets

This utility is 'Quik' in two ways:

  1. Easy for the user to enter the input for the plot --- and manage many plot options --- in a single window.

  2. Once the input is entered, the plot is rendered in a fraction of a second by a click on the 'UpdatePlot' button.


SCREENSHOTS of the GUI

Finally, in 2017, I got around to converting (and vastly improving) some old 'feHandyTools' code for this 'math expression' plot utility, and I ended up with the GUI seen in the following image.

Note that when the GUI first comes up, it is populated with some sample titles and a sample math expression --- as well as

  • four x-and-y-axis min-max entries,

  • a couple of x-and-y tic-mark-distance entries, and

  • a scale widget initialized to request 20 plot points be calculated.

When the GUI starts up, this sample input is rendered as a line-plot in the canvas area.

The title names indicate where the 3 types of titles initially appear on the GUI. The user can actually 'drag' these 3 titles around to different places on the GUI with a mouse. Just click on a title, hold down the button (button-1), and drag to a new position. Then release the button.

In fact, you can 'whip' titles out-of-sight --- off an edge of the 'canvas'. If you want the titles back, you can simply click on the 'UpdatePlot' button.

AND ... you can 'drag' the tic-mark labels. If you decided there are too many, you can 'whip' them off the canvas.

You are not given the option to drag the data points, because you could end up with a plot that is not in 'sync' with the math expression shown in the 'Expression' entry field of the GUI.

BUT you can change the shape of the plot by simply changing the math expression (for example, some coefficients in the expression) and then click on the 'UpdatePlot' button.

I could have used a more complex math expressin instead of this simplistic one. In fact, at the bottom of the script --- in the 'Additional GUI Initialization' section --- there are some other sample math expressions that could be activated instead of this simple linear expression in x.

    Note that a requirement is to enter the 'x' variable in the form '$x'. This helps make clear what the 'independent' variable is in this 'function of x', f(x).

    The y-values of the data points will be calculated based on the equality y = f(x).

    It is advisable to include the decimal point in any numeric parameters, such as coefficients, in the math expression.

---

The user has control of the 'domain' of the plot via the 'XaxisMin' and 'XaxisMax' entries.

And the user has control of the 'range' of the plot via the 'YaxisMin' and 'YaxisMax' entries.

The user has control of the tic-marking of the axes via the the 'XticDist' and 'YticDist' entries.

---

To show some of the plot options:

  • I clicked on the 'CanvasColor' button and used an RGB color selector GUI (a 'SELECTORtools' 'tkGooie' script presented on another web page) to change the canvas background color to black --- RGB(0,0,0).

  • I clicked on the 'Points' checkbutton to cause markers to be drawn, indicating the data point locations.

Then I clicked on the 'UpdatePlot' button. The resulting GUI is shown in the image below.

    When we are all working on 'retina display' monitors --- resolution of more than 2000x1500 for desktop computers --- like WQXGA = 2560x1600 --- then the jaggies in angled line segments may be unnoticeable. The images above were captured on a 1024x768 monitor.

I could (eventually) include a lot of code in the script to check for numeric input errors in the six numeric data 'entry' fields.

    I could adapt 'edit_inputs' and 'decimal_check' procs in Converter-Selector 'tkGooies' such as the tkWeightConvertSelect 'tkGooie' script.

But for the initial release of this script, I decided to rely on the 'friendly' error messages that come from the Tcl-Tk 'wish' interpreter --- as demonstrated in an image on the PlotQuik Points(and Lines) from XY Data Entry page.


A second math expression example

To demonstrate a less simplistic math expression, I entered a quadratic expression (a second-degree polynomial) in the 'Expression' entry field.

    In the 'Help' text that can be shown in a separate popup window via a click on the 'Help' button, one can see a list of the math functions (like sin, cos, tan, log, pow, sqrt, abs, int, round, etc.) that are Tcl math functions available for use in the math expression.

    In addition, the 'Help' text includes some sample math expressions that can be copied-and-pasted from the Help window into the math expression entry field of the GUI.

For the following image:

  • I clicked on the 'CanvasColor' button and used the RGB color selector GUI (mentioned above) to change the canvas background color to a rather dark magenta --- RGB(148,0,148).

  • I clicked on the 'Points' checkbutton to request that markers be drawn, indicating the data point locations.

Then I clicked on the 'UpdatePlot' button --- and found that I needed to make some adjustments to the input. I reset the XaxisMin, XaxisMax, XticDist, YaxisMin, YaxisMax, YticDist values --- and used 'UpdatePlot' until I got a nice looking plot.

Then I used the 'GetImg' button to get 3 GIF file images to put on the canvas. (They appear on the lower right of the canvas. I dragged each image to a different location on the canvas.)

The resulting GUI is shown in the image below.

In the quadratic expression above, I used the 'pow' function to express x-squared as 'pow($x,2)' and x as 'pow($x,1)'. This was to indicate how one could deal with much higher powers of x in a relatively compact form.

I could have entered x-squared as '$x * $x' and x simply as '$x'. To be clear, the math expression

(2.0 * pow($x,2)) + (3.5 * pow($x,1)) + 4.0

could have been written

(2.0 * $x * $x) + (3.5 * $x) + 4.0

I included plenty of parentheses to make it clear how the operations should be performed --- even though Tcl observes the usual precedence of multiplication over addition.

---

Note that the magenta background color is rather dark. This 'tkGooie' script is programmed to use WHITE on dark backgrounds, for text (titles and tic-mark-labels) and for lines (connecting data points and making axes and tic-marks) --- instead of BLACK, which is used for lighter/brighter backgrounds. Hence the white lines and text in the image above.


A third math expression example

To demonstrate a still less simplistic math expression, I entered an expression that adds two sinusoidal functions together --- a lower frequency and a higher frequency.

    In this expression, I used '$pi' to call on a variable holding a very accurate value for pi.

    If you ever need the 'natural' number 'e', you can use '$e' to call on that value.

In this case, I had to change the 'Number of Xvals' (via the 'scale' widget) from the default of 20 to a much higher value --- in this case, 200. (With 20, the plot is 'choppy' --- and does not reveal the higher frequency oscillations.)

I turned on the 'Points' checkbutton so that one could see the data points used to make a fairly smooth curve plot. And I set the canvas background color to a rather bright cyan --- RGB(0,230,230).

I also turned on the 'Border' checkbutton so that a border (a line) would be drawn around the plot.

After setting some suitable values for the plot limits, I clicked on the 'UpdatePlot' button, and I got the following plot.

A few other features

The 'DwnCan' and 'UpCan' buttons can be used to decrease and increase the size of the canvas plot area. With each click, the plot is redrawn to fit nicely inside the new size of the canvas.

---

The 'Help' button on the GUI can provide more extensive help than the brief guide on the left side of the GUI --- for example, to explain that the 'DwnCan' button may not work if the user has maximized the GUI window via the user's window manager. (Simply 'Unmaximize' the window with that button on the window title bar. Then the 'DwnCan' button will work again.)

---

I have discussed most of the buttons at the top of the GUI --- but not the 'Print' buttons.

The 'Print' buttons create a Postscript file in a '/tmp' directory. The 'PrtPreview' button uses a PDF/Postscript viewer utility --- such as 'evince' --- to show the Postscript file that is created.

And the 'Print' button uses a print-command --- shown in an 'entry' field at the top-right of the GUI --- to send the Postscript code to a user's printer.

The temporary-files-directory, the PDF/Postscript viewer-command, and the print-command can be changed by the user who downloads this script by changing 3 variables in 'set' statements at the bottom of the script in the 'Additional GUI Initialization' section:

  • DIRtemp
  • PSviewer
  • PRINTcmd

For the print command, I found that the program '/usr/bin/cupsdoprint' of the CUPS printing system worked quite nicely --- on my Ubuntu 9.10 Linux system --- with the set of parameters seen in this code.


Not a Toy

Note that this GUI is not meant to be a toy. Plots of science-engineering functions, econometric functions, probability distribution curves, etc. could be used to show that this GUI is meant to be an actual 'productivity' tool --- a free and open-source one.


DESCRIPTION OF THE CODE

Below is the code that produced this GUI.

I follow my usual 'canonical' structure for Tk code, for this Tk script:



  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms,
     text-array-for-labels-etc, win-size-control).

  1a) Define ALL frames and sub-frames.
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  3) Define keyboard or mouse/touchpad/touch-sensitive-screen
     action BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.


This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include from other scripts (code re-use).

I call your attention to step-zero. One new thing that I started doing around 2014 is using a text-array for text in labels, buttons, and other widgets in the GUI. This can make it easier for people to internationalize my scripts. I will be using a text-array like this in most of my scripts in the future.

All the 'set' statements for the text array, 'aRtext', are in one contiguous section toward the top of the code.


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus Tk scripts, so far), I provide the four main pack parameters --- '-side', '-anchor', '-fill', and '-expand' --- on ALL of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

I think I have found a good setting of the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets of this GUI. In particular ...

The 'canvas' widget expands/contracts appropriately when the window size is changed --- for example, during use of the 'DwnCan' and 'UpCan' buttons.

Furthermore, 'button' and 'label' widgets stay fixed in size and relative-location as the window size is changed. Entry fields x-expand if the window x-expands.

If anyone wants to change the way the GUI configures itself as the main window size is changed, they can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets --- to get the widget behavior that they want.

---

Additional experimentation: You could change the fonts used for the various GUI widgets and plot titles. For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'. Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding. And I have included the '-relief' parameter on the definitions of frames and widgets. Feel free to experiment with those 'appearance' parameters as well.

---

Note that the 'CanvasColor' button calls on an RGB color-selector-GUI script to set the canvas background color.

You can make that color-selector script by downloading the code from the page offering 'a non-obfuscated color selector GUI', on this site.

You can put that color-selector Tk script in the same directory with this script.


Some features of the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

See the 'PROCS' section of the code for a list of the procs that are used in this Tk script.

The main plotting code is in the proc 'update_plot'. See the comments in that proc for details on how the plotting is implemented.

Here is a quick view of how each of the procs are 'triggered'.



   'update_plot'            - Called by the 'UpdatePlot' button --- and by
                              the 'downsize_canvas' and 'upsize_canvas' procs
                              --- and at the bottom of the script, in the
                              'Additional GUI Initialization' section.

   'set_margins'            - Called by the 'update_plot' proc.

   'get_deciPlaces'         - Called by the 'update_plot' proc.

   'format_deciPlaces'      - Called by the 'update_plot' proc.

   'itemSelect'             - Called by a ButtonPress-1 binding on the canvas.

   'itemMove'               - Called by a Button1-Motion binding on the canvas.

   'draw_points'            - Called by the 'update_plot' proc --- if the
                              'Points' checkbutton is ON.

   'draw_border'            - Called by the 'update_plot' proc --- if the
                              'Border' checkbutton is ON.

   'getSet_canvasColor'     - Called by the 'CanvasColor' button.

   'set_plotColors'         - Called by the 'getSet_canvasColor' proc --- and
                              at the bottom of the script, in the
                              'Additional GUI Initialization' section.

   'blackORwhite_farthestFromHexRGBcolor'
                            - Called by the 'set_plotColors' proc.

   'augment_hexRGBcolor'    - Called by the 'set_plotColors' proc.

 Other, utility procs:

   'downsize_canvas'        - Called by the 'DwnCan' button.

   'upsize_canvas'          - Called by the 'UpCan' button.

   'resize_win'             - Called by the 'downsize_canvas' and
                              'upsize_canvas' procs.

   'getPut_image'           - Called by the 'GetImg' button.

   'print_preview'          - Called by the 'PrtPreview' button.

   'print_plot'             - Called by the 'Print' button.

   'popup_msgVarWithScroll' - Called by 'Help' button.


A fervent hope

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments (especially in the 'update_plot' proc), the code might look too cryptic --- and potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch the latest music/movie/TV/actors-guild/foreign-press/ Broadway/athletes/...... awards show.


THE CODE

Here is a link to CODE for the script 'plotquik_LinesPoints_mathExprYatX.tk'.

To browse the code, click on the link. To download it:

With your web browser, you can 'right-click' on this link --- and in the menu that pops up, select an item like 'Save Link Target As ...' --- to save this file to your local computer.

Then you can rename the file to remove the '.txt' suffix. Make sure that you have execute permission set on the file --- in order to execute the script.


SOME POTENTIAL ENHANCEMENTS:

Several possible enhancements come to mind, for this 'xy plot from a math expression GUI' utility:

  • Numeric-data editing:
    As mentioned above, some 'edit_inputs' and 'decimal_check' procs from other 'tkGooie' scripts could be modified to provide 'more dedicated' data checking for the six numeric data-entry fields.

    If in using this utility I find that the numeric checks by the 'wish' interpreter on the numeric data (and its 'Application Error' dialog window) do not suffice, then I may add some procs to this code, to implement numeric data checking.

  • Math expression syntax checking:
    This Tk GUI script is depending on the 'wish' interpreter to show a friendly 'Error' dialog window when the interpreter has a problem with the math expression that a user entered.

    If in using this utility I find that the syntax checking by the 'wish' interpreter on the math expression does not suffice, then I may try to implement some method of math expression syntax checking that avoids the 'insufficiencies'.

  • Additional control over tic-mark drawing:
    We could allow a tic-distance to be preceded by a minus sign, say, to signal that ticmark labels are not to be shown --- except at the ends of the axes.

Since I have not used this script for a large number of tests with widely varying ranges of data, there are probably some other enhancements that may be suggested by further usage.

If I ever find that I am using this utility and I find that any of the features above are highly advisable to add or change (or implement in a different script), then I may return to this script to add/change/implement that feature.


IN CONCLUSION

As I have said on quite a few other Tcl-Tk code-donation pages on this site ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.

Bottom of the page for this
PlotQuik Lines (and/or Points)
from a Math Expression
'tkGooie'
--- a utility in the FE 'tkGooies' system,
in the 'PLOTtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

This FE web page was created 2017 Sep 28.

Page was changed 2019 Feb 23.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 13.
(Specified image widths in percents to size the images according to width of the browser window.)


If I ever post a copy of this code on the Tcler's Wiki site (wiki.tcl.tk) --- as a backup and alternative to this page, I plan to put a link to that page here.