you can create a
- VC8 DLL project for WinXX environments (should even work down to VC6 projects)
- shared library for POSIX systems.
Adjust the target path and perhaps the library directories. The same
is true for the examples .pro
QwtPlot3D supports Qt3 and Qt4. Older Qt versions than 3.0 are not
will never work - especially the 2.3.0 non-commercial version for
wrong please don't hesitate to contact me. I'll try to provide a
code fix for Qt versions >= 3.0.?.
The library requires OpenGL >= 1.1 or equivalent and a true
mode with 24 or 32 bits color depth.
The API Documentation has been created using doxygen. If you
prefer to generate your own version, you will find the configuration in
You can test almost all abilities of QwtPlot3D from within the
- Colors, fonts, normal vectors, mouse handling etc.
- Grid and FEM data reading from files (in
- Output to all pixmap formats supported by Qt
- Output to vector formats supported by gl2ps
- Plotting styles and resolution change on the fly
demonstrates vector graphics output utilizing gl2ps
means EPS, PS and PDF. See here
extensive discussion. gl2ps
compression. This leads to
significant smaller EPS
& PDF output and is therefore recommended. The zlib switch in
qwtplot3d.pro turns compression on or off. The default setting is OFF
for Windows and ON for all other systems.
So, it would be a good idea to get this example project up and
Calculations are performed as accurate
float.h for the precise value). This is mainly due to the autoscaler.
See e.g. here
for a topic related discussion.
// A simple example which shows how to use SurfacePlot
using namespace Qwt3D;
class Rosenbrock : public Function
double operator()(double x, double y)
return log((1-x)*(1-x) + 100 * (y - x*x)*(y - x*x)) / 8;
class Plot : public SurfacePlot
setTitle("A Simple SurfacePlot Demonstration");
for (unsigned i=0; i!=coordinates()->axes.size(); ++i)
coordinates()->axes[Z1].setLabelString(QChar (0x38f)); // Omega - see http://www.unicode.org/charts/
int main(int argc, char **argv)
QApplication a(argc, argv);
The code above shows the almost most simple application of a
SurfacePlot. Data are provided by a mathematical function object
(Rosenbrock). You can derive from this kind of classes by
A base for the other player
the widget itself - resides inside
The derived class makes only small adaptations to the standard
mainly providing scales and label for the axes and a boxed coordinate
system . The axes themselves are autoscaled.
and Keyboard Handling
Try Ctrl, Shift, Alt in combination with your wheel and left
mouse button to get a clue (or use instead your cursor keys).
The base class Plot3D implements the standard mouse and keyboard
behaviour. You can
perform shifts, turns, scales and zooms with your left mouse button and
combinations of Ctrl, Shift
have equivalents delegated to your wheel. You can also turn on or off
mouse handling entirely by using Plot3D::enableMouse () and
Plot3D::disableMouse (). The default behaviour can be changed with
Plot3D::assignMouse(). Keyboard handling has been implemented in a
Additionally, you can determine the speed of the performed
actions when using the keyboard.
Systems and Axes
Axes are subdivided by major and minor tics. You have full control over
tic length and orientation and also the line width of tics and the axis
body. Furthermore, the axes provide captions and numberings. Colors,
fonts etc. of all of this parts are customizable. Additionally, all
with linear scaling are autoscalable, giving them major tics at
positions which are
multiples of 1,2,5 * 10^n relative to the underlying interval. 12 axes
together form the coordinate system. It can be visualized as frame or
the ability to autoswitch axis decoration and visibility of axes
themselves depending on the position in the 3D-space. Most axis
properties can be changed for the whole coordinate system at once or
separately for single axes. An axis is
also part of the color legend object.
Axes are highly customizable regarding label content and tic
distribution. Linear and logarithmic scales are supported by default.
Other variants, like different numbering schemes (date/time, letters
etc.) and user-defined scales are possible.
'axes' project for example implementations.
class operates comparable to Function
a callback operator(x,y,z) - able to assign to every single data point
a RGBA value. In many cases it is sufficient to do this in an
z-coordinate dependent manner.To satisfy this demand, the StandardColor
class has been provided. The class has a vector<RGBA> member and
the operator() distributes the entries equidistant between the extreme
z values of the data. The Plot3D constructor enforces as standard
behaviour a StandardColor object with 100 RGBA entries.
The mesh2 data color dialog gives a good example of changing a standard
color. The widget is a specialized Qt file
dialog for reading palette files (*) . The files include at most 256
different colors (because originally designed for 256 color graphics),
but the color vector itself (and also the file reading routine) is by
no means limited to this number. To give a plot a new color use Plot3D::setDataColor
. Also, simple RGBA Color attributes are available for background,
meshes, labels, title etc..
*shameless stolen from the fractint
Some Plot3D class member encapsulate (partially) OpenGL's
lighting features. This means material and light source properties and
light source positions. You can set up to 8 different lights (OpenGL
guaranteed minimum). Beware, that some calculations become very slow in
this case. Lighting is considered experimental
moment, and works not yet in a completely precise way. This will be
fixed in the future.
All Fonts available for Qt are also provided for screen representation
(including Unicode) and pixmap output. A special question concerns
vector formats. At the moment I
have no plans in supporting FreeType or similar solutions. But you can
still use the gl2ps provided mixed TeX-EPS/PDF variant, producing pretty satisfying results
Generally spoken, an Enrichment provides additional visual objects
depending on data properties. Furthermore, the base class has been well
embedded in the plots framework to draw these objects in a reasonable
efficient manner. Enrichments come in six flavors: vertex-, edge-,
face-, voxel-, graph- and widget-driven (the term 'graph' refers to the
object as a whole). Widget Enrichments are somewhat special, because
they describe entities outside the data object. In future
versions they will also gather things like title and legends. The
variants 2)-6) are
future work, but
the yet implemented vertex based Enrichments are still remarkable
The primary impulse came from the wish
to add some small objects (esp. marker etc.) at dedicated positions to
the plot. The result is surprisingly more far-reaching. The screenshot
entire new plotting
style utilizing Vertex Enrichments. The small red-white
marker objects are part of the generating Enrichment
object as well as the bars themselves. Beginning with version 0.2.3
QwtPlot3D supports user defined plotting styles. But not enough,
Plot3D provides a container allowing the injection of arbitrary
Enrichments also in other contexts. See the class documentation for
closer explanation. The
contains the application from which the screenshot has been obtained.
File I/O in QwtPlot3D works in one of the following ways:
a) Define a global
bool MyHandler(Plot3D* plot,
QString const& fname)
SurfacePlot* tmpplot = (SurfacePlot*)plot;
// ... do your in- or output here
b) ... or an enhanced
version - a Functor:
// The next both must be implemented:
Functor* clone() const
// The framework assumes the
// so provide a heap based object
return new MyHandler(you_name_it);
bool operator()(Plot3D* plot, QString const&
// Do highly complex I/O-things here
In any case the new function/functor has to be registered by one of the
following static functions:
const& format, Functor const& func)
bool IO::defineInputHandler( QString const& format, Function func)
The same procedure applies to the
output variants. If you
wish to modify the
behaviour later, you can either replace the actual handler with a
call to define...Handler() conveying a fresh function/functor or - in
the case of a functor -
manipulate the yet installed object:
MyHandler* own_format_handler =
handler for all of the QImageIO pixmap formats are available, in
a functor for PDF, PS and EPS
output (see also here
QwtPlot3D supports one general and some special forms of native data
A general approach has been provided in form of the 3 SurfacePlot
**data, unsigned int columns, unsigned int rows, double minx,
double maxx, double miny, double maxy)
**data, unsigned int columns, unsigned int rows, bool uperiodic=false,
const &data, Qwt3D::CellField
The 3 functions in this order have ascending generality:
- The first one deals with data on top of
plane grids: z=f(x,y) ;
- The 2nd form maps also deformed rectangular grids x=f(u,v),
y=g(u,v), z=h(u,v) u and v can be periodic - both or
one of them.
- The last variant eventually provides
support for more free formed meshs, divided in a node- (the TripleField
argument) and a polygon- (the CellField) part. This kind of
data is common for FEM and CAD applications but not limited to them. It
is the 'swiss knife' because it is of course able to represent all the
other variants. The question here is performance (still not too bad).
Functions & Parametric Surfaces:
Setup a function object. To do so, inherit from the Function class and
write your own version of Function::operator()(double
x, double y).
the domain and perhaps limitations for the range and call
all.See also Function and the implementation
of concrete functions in 'examples'. Parametric surfaces are
generalizations of functions. In a similar way, ParameterSurface::operator()(double u,
must be replaced. (u,v) domains might have rotational
symmetry. The drawing routines of SurfacePlot are aware of this,
if you provide the necessary information with ParametricSurface::setPeriodic().
682 682 682 682 912 924 928 928 932 ...
Reading of the aforementioned file type, utilizing the first of the
above mentioned functions.
See NativeReader for additional information. Write your own reader
classes in this spirit. It should always be enough to provide
appropriate data for SurfacePlot::loadFromData.
bool NativeReader::operator()(Plot3D* plot, QString const& fname, QString const& format)
unsigned int xmesh, ymesh;
double minx, maxx, miny, maxy;
if ( !collectInfo(file, fname, xmesh, ymesh, minx, maxx, miny, maxy) )
/* allocate some space for the mesh */
double** data = allocateData(xmesh, ymesh);
for (unsigned int j = 0; j < ymesh; j++)
for (unsigned int i = 0; i < xmesh; i++)
if (fscanf(file, "%lf", &data[i][j]) != 1)
fprintf(stderr, "NativeReader::read: error in data file \"%s\"\n", (const char*)fname.local8Bit());
if (data[i][j] > maxz_)
data[i][j] = maxz_;
else if (data[i][j] < minz_)
data[i][j] = minz_;
/* close the file */
((SurfacePlot*)plot)->loadFromData(data, xmesh, ymesh, minx, maxx, miny, maxy);
All the examples can be found in the
executables are gathered in the
|The almost most simple plot
|Demonstrates the autoswitching
of axes, and the parallel use of 2 plot widgets in a splitter windows.
|Manipulation of axes
parts, like tics, labeling (including the application of user-defined
numbering); Positioning for labels; Nonlinear scales
|The running version from the Enrichment discussion.
|Main example. It includes (most
of) the other features not found in specialized examples. There are
still things, hidden in the API. There is a thesis.tex file under the
sources of mesh2. It can be used to produce complete output (esp.
vectorized numbering etc.) in connection with the libraries PDF and PS