This is another 2D plotting tool for Julia language. It is based on
C library, which is based on
QWT library which is based on
QT library. Also,
KDE Marble libraries are used.
Current version supposed to work for
Windows and for
Linux x64 bits.
It is very useful for data analysis (like if you have a dynamic systems with a big state vector, sometimes its difficult to say how one variable influence other variable).
how to install it
- just install it as usual Julia package, with
] add QWTWPlot.
BTW, this is possible because of https://github.com/JuliaPackaging/BinaryBuilder.jl
look at usage example here: https://github.com/ig-or/QWTWPlot.jl/blob/master/src/qwexample.jl and for callback also here https://github.com/ig-or/QWTWPlot.jl/blob/master/src/cbtest.jl,
] dev QWTWPlot
the most useful features
all plots are "connected" - this makes it very easy to analyze small parts of long dynamic process with a lot of variables; what this means:
- when you point a 'marker' on one plot, you can see markers on all other plots pointing on the 'same place'
how "markers" looks like:
- after you select some interesting area on plot "X", and then press right plot button ("CLIP" button), all the other plots are resizing accordingly ("time" interval on all other plots became equal to this interval on plot "X")
First, select some interesting area on one plot:
After this, press "clip" button:
BTW, if you do not want that all plots do resize after this, use
qclipgrp function. See more details in qwexample.jl about how to use it.
- you can create a "Power Spectral Dencity" plot for some (selected) area of your plot, by pressing "f" button
First, select a desired time range with ZOOM tool and then press "f" button:
After this (in new small window) select lines for which you'd like to create a PSD plots, select "window size" (not very big) and close this small window (Alt+F4?). Enjoy new PSD plot! You can easily estimate the frequency of the original signal. Again, PSD was created only from the data which were visible on the 'original' plot.
- you can draw a 'meta-window' with list of all plots; This is very convenient in case you have 10 - 15 plots or even more
this library have UDP client&server, so it can display incoming "marker" messages and send out marker positions when using "marker gui"
possible to use log axis scale
Now its possible to create 3D lines and surfaces (because of MathGL). There are a few details about how to do this in the example. https://github.com/ig-or/QWTWPlot.jl/blob/master/src/qwexample.jl
also, it's possible to remove or change existing lines on plots (see an example how to do it)(implemented for simple 2D plots).
- M switch to "marker mode"
- P switch to "pan mode"
- Z switch to "zoom mode"
- V add/remove "(permanent)vertical marker" to the current marker position
- Shift+V same as V but for all the existing plots which can support it (simple 2D plots)
- A add/remove an "(permanent) arrow-like marker" to the current marker position.
now you can make your own function to be called, when you do a mouse click on a plot, or pressing 'clip' button.
cbtest.jl supposed to have more examples about it.
following (exported from a module) struct is a parameter to your callback function:
""" information for the callback function about the mouse click """ struct QCBInfo type::Int32 # callback type ('1' for simple mouse click.. something else in case 'external UDP message info') plotID::Int32 # ID of the plot window lineID::Int32 # ID of the closest line index::Int32 # closest point index xx::Int32 # x window coord yy::Int32 # y window coord # closest point info x::Float64 # X coord y::Float64 # Y coord z::Float64 # Z coord (probably zero, when 'type' == 1) time::Float64 # time info label::String # label of the selected line end
lets create and test a simple callback function:
function my_callback(q::QCBInfo) @printf "plot %d, line %d (%s); index = %d; xx = %d; yy = %d \n" q.plotID q.lineID q.label q.index q.xx q.yy @printf "x = %f; y = %f; z = %f; time = %f\n\n" q.x q.y q.z q.time end
and register it:
now, you can click on the plots (when "marker mode" enabled! usually this means that 'arrow button' was pressed)
and see how your callback is working.
BTW it is called from the different Julia thread, so be careful. But sometimes it's OK to use
qwtw functions from a callbacks.
cbtest.jl has an example how to use qwtw functions from a callback.
Also, it's possible to setup a callback to a 'clip' function. following (exported from a module) struct is a parameter to your callback function:
""" information about the 'clip' callback (when the user is pressing 'clip' button ) """ struct QClipCallbackInfo t1::Float64 # time 1 (left) t2::Float64 # time 2 (right) clipGroup::Int32 # clip group (every plot has its group) havePos::Bool # true if x y z are valid x1::Float64 # point corresponding to time1, if any y1::Float64 z1::Float64 x2::Float64 # point corresponding to time2, if any y2::Float64 z2::Float64 end
How to define and register very simple 'clip' callback:
function clipCallback(q::QClipCallbackInfo) @printf "\nclipCallback!\n\tt1 = %f\n\tt2 = %f; clipGroup=%d\n\n" q.t1 q.t2 q.clipGroup return end qsetClipCallback(clipCallback)
are stored in ~/.qwtw/settings.json file. In rare cases you may want to update this file manually.
pickerDigitsNumberis the number of digits (with pointer coordinates) displayed near mouse cursor when you press left mouse button on a plot window (in 'marker' mode).
- 'udp_server_port' and 'udp_client_port' port numbers have to be available to UDP protocols. Most functionality is implemented via shared memory, but there is still some parts relying on UDP.
I suspect the underlying qwtw library is not thread-safe, so would not recommend to use it from different julia threads simultaneously. But you should be able to call most of the qwtw functions from a 'callback' (due to special 'guard' features).