plotchart

plotchart , a tklib package by AM, provides simple yet versatile plotting and charting. AM is also involved in the Plplot project, which provides lower-level and more flexible, but more complicated plotting facility.

See Also

Plots and charts
Use an xy-plot to edit data series
AM 2001-11-23 I have been experimenting with adding interactive features to Plotchart, but you can use the current version in an interactive environment already:
Experimenting with canvas and scrollbar
AM 2008-08-20: When you have many items for a time chart or a Gantt chart, being able to scroll up and down is useful. But the title must remain visible, as well as the time axis ... So here is a small experiment:
Extensions to Plotchart 2
Extensions to Plotchart
An interactive tutorial for Plotchart
the canvas as a data store
arjen 2010-08-13T03:24:42: Inspired by an article (http://www.ibm.com/developerworks/library/x-svgclientside/ ) by Cameron Laird on web-interfaces using SVG features, I came up with this
contour plot

Documentation

official reference
An interactive tutorial for Plotchart
The humble beginnings of a tutorial

Examples

Plotchart gallery
Drawing a wind rose
an example by AM

Misc

Bryan Oakley 2005-05-09: I notice that the code uses [$w cget -width] everywhere it needs a value to compute the width of the graph. My first thought was that this seemed wrong -- it ought to use [winfo width $w] so that it will be drawn to fit the window in case the window grows because of the way it is packed/gridded. Of course, this also means the graph will shrink if the viewable portion of the canvas is less than the configured width/height of the canvas.

I can see a case for each behavior, so I'm wondering if it would be useful to have a configuration option such that one could do [$plot configure -width "actual"] or [... -width "request"]. Of course, I can simulate that by adding code to do something like [.canvas configure -width [winfo width .canvas] after I pack/grid it, but I'm not fond of that solution.

JE: What are the cases for the current behavior? It seems to me that the actual width is always the right thing to use, I can't think of when you'd want it to use the requested width (if the two differ).

A third option might be to specify an actual value, e.g. $plot configure -width 200 for the case where you have a really large plot that you want to scroll around in a small canvas.

I'd be willing to contribute the code for this option if you think it would be useful.

AM 2005-05-10: I have not given much thought to this issue, I must admit. Resizing the plot's canvas may have to result in one of several things:

  • The plot is redrawn to fit the new size (using the new width and height)
  • The plot is redrawn to fit the new size but the ratio width/height remains the same
  • The plot remains as it is (for instance to enable scrolling ...)

I can see all of these happening - should there be an option for dealing with this? Code contributions are welcomed of course.

PWE 2007-08-06: Now I've started using plotchart, some comments/questions on the xy-plots. 1) If the title of the chart is long, it overwrites the text of the Y axis. 2) Is it possible to have a custom format for the X or Y axis labels. For instance when the X axis is time, to have the labels display dates? Something like blt's axis configure myaxis -command myformat 3) Is it possible to have multiple charts on a single canvas? So one can make a report with multiple graphs, and print it on a single sheet of paper?

AM 2007-11-22: Sorry for noticing these questions so late:

  1. I will have to look into that one. Note that you can use \n to break the title in separate lines
  2. Yes: $plot xformat "%e12.4 " for instance (IIRC, I should check the code and the docs, but the functionality should be there!)
  3. When I used its predecessor, emu_graph, I needed to plot multiple charts too. This turned out to be somewhat tricky, as things in one chart, started to interfer with the other. When I wrote Plotchart using my knowledge of and experience with emu_graph, I decided to use one canvas per chart for that reason and because I could implement a kind of clipping more easily that way (I use filled rectangles for that). That means the basic design does not allow for more than one chart per canvas. However, when you use a cloning technique (and have no fear for data outside the shown region), it may very well be possible to copy the contents of several canvases into a single canvas for printing.

JHJL 2007-12-02: Got the latest sources from CVS but ran into a couple of problems:

  1. The pkgIndex is out of synch (states 1.3.1, should be 1.4.0)
  2. There are some debug lines in the plotaxis.tcl (two puts and a console show)

Can anyone explain how to plot data on the isometric plot - I see code to draw circles and rectangles but can't get ordinary x,y data points to plot. And as a bonus, how does one draw gridlines on an XY plot (or isometric plot)? All help gratefully received!

AM 2007-12-04: I will have to look into your questions about pkgIndex.tcl and plotaxis.tcl - thanks for noting these.

I intended isometric plots as a way to easily draw scale models or simple geographic plots. What kind of representation would you like for x,y data points? If it is dots, then small circles ought to do (the canvas does not support "real" dots, i.e. individual pixels).

Xy-plots have methods to draw grid-lines:

$p xticklines 
$p yticklines

draw vertical and horizontal lines, corresponding to the labels along the x and y axes, respectively.

If you are missing something from the user documentation, please let me know.

JHJL: Thanks Arjen, Plotchart is a very nice library to have to hand. I plot a lot of X,Y positional data (e.g. aircraft, ships etc) and therefore need to keep the grid square. I had hoped the isometric plot would help here... I will look into your suggestions for drawing the grid lines (would be nice as an axis option though :)

AM: Ah, now I understand - well, I might be able to help out with that :). I need to do some work on Plotchart anyway and this should be easy enough (just need a clear idea on what needs to be done).


VL 2010-01-21T05:07:41:

Can i bind events to dots for example on a XYplot, i used to tag each of my points and then bind events to that tag. For that i need an ID on the canvas.?


arjen 2010-01-21T07:46:43:

the latest version does have some experimental facilities for that. Perhaps not complete, but let me know what you are missing and I will see if/how I can add it.


VL 2010-05-17T12:11:01

In order to bind events to components on the canvas created through plotchart, I finally had to modify the package a bit. The result of this modification is that the procedure that creates dots now returns their ID on the canvas. This way i can easily bind different events on each dot of my graphic.

I did have to roughly understand how the library worked, and stumbled upon a list of IDs for each item on the canvas created by the package. Unfortunately, i did not manage to fully understand how this list worked and therefore how i could use it.

I can understand the list of IDs is important in case the user wants to plot a line with symbols, or for many other reasons (i only use XYPlots with several series).

Really waiting for some documentation/explanations on how the IDs are saved in this list. An example would really be neat! :)


arjen 2010-06-09T08:04:03

In version 1.8.3 I have added some lacking information on the subcommands bindplot and bindlast. They can be used for defining interactive features. The relevant demonstration script is plotdemos12.tcl. See the CVS-repository at http://tcllib.sf.net/ .


RaviChandran 2010-06-21T23:59:44

I have started using plotchart recently. Is it possible to generate graphs in Japanese language? Any help or samples towards that would be much appreciated.

AMG: I freely admit that I know nothing about plotchart, but I do have a basic understanding of Tcl. One thing I know is that Tcl has excellent support for international character sets, and as such should have no difficulty handling Japanese.

set languages {en English es Español fr Français ja 日本語 vi "tiếng Việt" sa संस्कृतम् fa فارسی}
dict get $languages ja

You may notice from the Farsi example that Tcl seems to have trouble doing right-to-left text. Maybe there's something special I have to do to make that work right.

Maybe plotchat internally assumes ASCII, but I wouldn't know. So I suggest you try it and see, and let us know what happens.

AM 2010-06-22: Plotchart itself does not assume anything about the strings, so I imagine that drawing these non-Latin alphabets will work fine. However:

  • The saveplot subcommand will probably not do the job correctly: PostScript is very limited in its support for non-ASCII characters.
  • If you use X Window, you may need to update your fonts - MS Windows seems to be more inclined to display non-ASCII characters out-of-the-box.

AM 2010-06-22: I just tried it: the title is displayed correctly with the above string on Windows XP. So you should be able to display any text in Japanese with the exception of the saveplot subcommand. You should save the window's content using the img package. Alternatively, you may be able to create PDF-files using a package like pdf4tcl that do render the Japanese characters correctly.

olly 2010-08-02T11:35:55:

I'm using Plotchart 1.9.2 and can't seem to find a way to display the ticklines BEHIND the actual data. I'm using lightblue ticklines and the effect is quite noticeable when using dark colours for the plots. I also have limit lines which I plot using green and when these happen to coincide exactly with a tickline they are not visible at all. Is there any way to force the data to appear on top of the ticklines ? Oh yes, I'm using TCL 8.6

TR: Consider this a bug (but see below). I cannot see where it occurs but you can do a workaround, when you apply this command as the last one in your plot:

$canvas lower ytickline data

Replace $canvas with your canvas path and ytickline with xtickline, if you have vertical ticklines and not horizontal ones.

AM 2010-08-09: I am not quite sure this is a bug ;). It is rather a design issue: if data lines pass over the axis, what should be visible, the data lines or the axis? An option would help, I guess, as there is no definite answer.

TR: Maybe you are right. Thinking a little more about it, I can see cases where it is desirable to have even the ticklines in front.


arjen 2010-09-02T03:12:12

Torsten Berg and I are working on more features for Plotchart (well, he is doing most of the work at the moment). One of them is animations - that will bring an animated chart like at [L1 ] within easy reach. Some screenshots: Pictures from Plotchart 2.0

ET 8/2021 - Here's some code I wrote to work around Plotchart's stripchart running out of memory since all the data shifted to the left is still in memory and growing. This is a problem with a long running monitor program. Besides running out of memory, it can slow down if you don't clean up once in a while.

There's a sub-command in recent versions called deletedata, and it just deletes all the canvas items with the tag "data". But this also clears the current display data as well. The following code will delete only the data points to the left of the chart, which have negative coords. Call it with the widget name you used to create the stripchart. I call it every modulo N times calling the plot method.

proc dtags {w} {
    set datatags [$w find withtag data]
    set thresh 0
    foreach tag $datatags {
        set type [$w type $tag]
        if { $type eq "line" ||  $type eq "polygon" } {
            set coords [$w coords $tag]
            lassign $coords x0 y0 x1 y1
            if { $x0 < $thresh && $x1 < $thresh  } {
                $w delete $tag
            }
        }   
    }
}

JHJL 2022-04-10: Is there a way to reduce the size of the margins used by the bar chart plot? For example, When I create a bar chart the left margin seems to be calculated in MarginsRectangle as $char_width*$text_width giving a value of 112. text_width is an argument to MarginsRectangle, it defaults to 8, but I can't work out how to set it via the createBarchart call. For the plot I am working on, I don't display the left axis & labels and I am not using the right axis either, so I am trying to maximise the width of the plot within the canvas.

Version 2.0 will need Tcl/Tk 8.5 and have these enhancements:

  • more drawing options and configuration possibilities
  • a kind of "style engine" for overall plot layout and style
  • support for animations
  • drawing of objects in plots (circle, rectangle, text, ...)
  • multiple plots on a single canvas (!)
  • support for advanced text rendering (subscript, superscript, ...)
  • more different box and whisker options
  • plotting of functions
  • support for custom plot methods
  • a number of bug fixes ...
  • (demo programme?)
  • (handbook?)

Bugs

AMG: The latest version of Plotchart (2.2.2) will not load: [L2 ] arjen: Thanks for reporting - it has been fixed.

AMG: Thanks, got it, and it works now.

APB: The plotchart in tklib0.6 needed a small modification to the pkgIndex.tcl to load correctly. More critically, it seems to have a bug where the '<plot> bindplot' command won't fire when it's triggered on top of data points in an xy plot but will correctly fire when in empty parts of the plot. This is quite a nasty bug, rendering the binding useless for me at the moment.

ol.bond: The plotchart method <rescale> doesn't work properly when both the left and right axes are used. (rescale only one left axis)