an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
format string for printf tick labels, see https://en.wikipedia.org/wiki/Printf_format_string documentation for details on format strings The first data parameter is the tick value as double an the second is tickUnitName as string. The following image shows an example for "y=%+.2f":
format string for printf tick labels, see https://en.wikipedia.org/wiki/Printf_format_string documentation for details on format strings The first data parameter is the tick value as double an the second is tickUnitName as string. The following image shows an example for "y=%+.2f":
calculates the tick spacing for a linear axis that spans awidth and that should show at least JKQTPCoordinateAxisStyle::minTicks JKQTPCoordinateAxisStyle::ticks.
calculates the maximum width and height (returned as QSize) of all tick labels. Ascent and descent may also be returned in the two additional pointer arguments-
calculated property: width of plot on axis (calculated by calcPlotScaling() )
Detailed Description
this virtual class is the base for any type of coordinate axis, to be drawn by JKQTBasePlotter.
Classes derived from JKQTPCoordinateAxis implements all the functionality needed for a coordinate axis:
transform world to screen coordinates and vice versa
draw the axis (implemented by child classes!) with these elements: axis lines, ticks, tick labels, axis label, x/y=0 axis
measure the axes in screen coordinates
load and save the settings to an ini file
Most of the actual draw and measure functions have to be implemented in descendents of this class (namely JKQTPHorizontalAxis and JKQTPVerticalAxis, as they are specific to whether the axis is drawn horizontally or vertically.
Each axis is split up into several parts, as depicted in this image:
Which parts to actually draw is set by the diverse properties.
Coordinate Systems and Transformations
The plot itself is positioned inside the widget (see Plot Sizes & Borders for details). You simply supply the widget dimensions and the border widths between the plot and the widget. The Object then calculates the size of the plot:
The plot shows the parameter range xmin ... xmax and ymin ... ymax. Note that if you plot logarithmic plots you may only plot positive (>0) values. Any other value may lead to an error or unpredictable behaviour.
From these parameters the object calculates the scaling laws for plotting pints to the screen. The next paragraphs show all calculations for x- and y-coordinates, ahough this class only implements a generic form. The actual calculation is also influenced by the parameters set in the child classes!
These parameters are common to all scaling laws. The next image explains these formulas:
The actual scaling laws may be derived from these equations:
Here denotes a point in pixel coordinates (green coordinate system) and denotes a point in the plotting coordinate system.
If you assume a linear scaling law.
you can derive:
If you have a logarithmic axis (i.e. we plot insetad of for a given base ) we get the same formulas, but with exchanged by . If we use the equation we finally get the scaling laws:
From these we can calculate their parameters with the same defining equations as above:
The object implements the above coordinate transformations in the (inline) method x2p(). The inverse transformations are implemented in p2x(). They can be used to show the system coordinates of the current mouse position.
Inverted Coordinate Axes
In some cases it may be necessary to invert the direction of increasing coordinates on an axis. One such case is image analysis, as computer images usually have coordinates starting with (0,0) at the top left and increasing to the right (x) and down (y). You can invert any axis by setting setInverted(true).
This section explains how this component draws the ticks on coordinate axes and the grids that may be drawn below the plots. In principle both - grids and axes - are drawn the same way, i.e. with the same step widths. There are two types of ticks and grids: The major and the minor ticks/grids. The major ticks also show a label that denotes the value they represent. Between two major ticks the axis shows JKQTPCoordinateAxisStyle::minorTicks small ticks that are not accompanied by a label. The next image shows an example of an axis:
For the labels this class also uses an algorithm that extimates the number of valid digits (after the comma) that are needed so that two adjacent labels do not show the same text, so if you plot the range 1.10 .. 1.15 The algorithm will show at least two valid digits, as with one digit the labels would be 1.1, 1.1, 1.1, 1.1, 1.1, 1.1. With two digits they are 1.10, 1.11, 1.12, 1.13, 1.14, 1.15. The class may also use a method that can write 1m instead of 0.001 and 1k instead of 1000 (the algorithm supports the "exponent letters" f, p, n, u, m, k, M, G, T, P. The latter option may (de)activated by using showXExponentCharacter and showYExponentCharacter.
For grids applies the same. There are two grids that are drawn in different styles (often the major grid is drawn thicker and darker than the minor grid).
The minor ticks and grid lines are generated automatically, depending in the setting of JKQTPCoordinateAxisStyle::minorTicks. These properties give the number of minor ticks between two major ticks, so if the major ticks are at 1,2,3,... and you want minor ticks at 1.1, 1.2, 1.3,... then you will have to set JKQTPCoordinateAxisStyle::minorTicks=9 as there are nine ticks between two major ticks. So the minor tick spacing is calculated as:
The same applies for logarithmic axes. If the major ticks are at 1,10,100,... and you set JKQTPCoordinateAxisStyle::minorTicks=9 the program will generate 9 equally spaced minor ticks in between, so you have minor ticks at 2,3,4,...,11,12,13,... This results in a standard logarithmic axis. If you set JKQTPCoordinateAxisStyle::minorTicks=1 then you will get minor ticks at 5,15,150,...
The major tick-tick distances of linear axes may be calculated automatically in a way that the axis shows at least a given number of ticks JKQTPCoordinateAxisStyle::minTicks. The algorithm takes that tick spacing that will give a number of ticks per axis nearest but ">=" to the given JKQTPCoordinateAxisStyle::minTicks. The Algorithm is described in detail with the function calcLinearTickSpacing(). To activate this automatic tick spacing you have to set autoAxisSpacing=true.
Axis Tick Units/Scaling
In some cases it is desired to put the axis ticks not at 1,2,3,... but rather at , , or any other unit than ,i.e.:
calculates the tick spacing for a linear axis that spans awidth and that should show at least JKQTPCoordinateAxisStyle::minTicks JKQTPCoordinateAxisStyle::ticks.
The algorithm used in here works as follows:
There is only a limited subset of allowed tick distances. These distances are 1 (resulting in 10 JKQTPCoordinateAxisStyle::ticks per decade, i.e. 0,1,2,3,4,...), 2 (5 JKQTPCoordinateAxisStyle::ticks/decade, i.e. 0,2,4,...), 2.5 (4 JKQTPCoordinateAxisStyle::ticks/decade, i.e. 0,2.5,5,...) and 5 (2 JKQTPCoordinateAxisStyle::ticks/decade, i.e. 0,5,10,15,...). So the axis is divided into decades that each is divided into JKQTPCoordinateAxisStyle::ticks, as defined above. With these preconditions the algorithm tries to find a tick increment which is one of the above distances multiplied by a power of 10. This increment is determined in a way, that the axis contains at least JKQTPCoordinateAxisStyle::minTicks JKQTPCoordinateAxisStyle::ticks:
The algorithm starts by finding a start exponent . This is a good (over)estimate for the biggest possible power .
now we set and .
now the algorithm cycles through all possible factors (starting from 10) and calculates . Then it checks whether is smaller than JKQTPCoordinateAxisStyle::minTicks (if yes the algorithm reached its end and can be used.
if is reached and checked false, then the algorithm decreases the exponent and returns to step 3.
Calculate the number of digits needed for the labels of an axis that starts at minval and where the tick spacing is tickSpacing.
This method determines how many digits to output for the labels on a coordinate axis. This is done by testing different digit numbers and comparing subsequent labels. If two labels are equal, then we need more valid digits to distinguish them.
calculate the scaling and offset values from axis min/max values
This is only executed when paramChanged==true, as otherwise the data has to be still correct. recalculating may be forced by caling calcPlotScaing(true);
calculates the maximum width and height (returned as QSize) of all tick labels. Ascent and descent may also be returned in the two additional pointer arguments-
calculates the next label from the given parameters.
Returns
true on success and false if there is no more label
Parameters
x
beforecall: the position of the label for which the text should be returned (or JKQTPCoordinateAxisStyle::tickStart for first call), aftercall: position of the next label (given in world coordinates!)
label
aftercall: text of the (input) tick label This is an empty string, if the label is not visible!
init
call this function with init=true to obtain the first label (at JKQTPCoordinateAxisStyle::tickStart)
format string for printf tick labels, see https://en.wikipedia.org/wiki/Printf_format_string documentation for details on format strings The first data parameter is the tick value as double an the second is tickUnitName as string. The following image shows an example for "y=%+.2f":
The user (or programmer) cannot zoom to a viewport that is larger than the range given to this function.
Parameters
aamin
absolute minimum of the axis
aamax
absolute maximum of the axis
Note
if the aspect ratio (set in the JKQTBasePlotter or JKQTPlotter) of this does not fit into the widget, it is possible that you don't see the complete contents!
the actually set range may differ from [getMin()...amax] in order to fullfill requirements e.g. for logarithmic axes or an absolute axis range (see setAbsoluteRange() )
if setRangeFixed(true) was called before this call, the axis range is fixed and this function has NO EFFECT!
the actually set range may differ from [amin...getMax()] in order to fullfill requirements e.g. for logarithmic axes or an absolute axis range (see setAbsoluteRange() )
if setRangeFixed(true) was called before this call, the axis range is fixed and this function has NO EFFECT!
the actually set range may differ from [amin...amax] in order to fullfill requirements e.g. for logarithmic axes or an absolute axis range (see setAbsoluteRange() )
if setRangeFixed(true) was called before this call, the axis range is fixed and this function has NO EFFECT!
format string for printf tick labels, see https://en.wikipedia.org/wiki/Printf_format_string documentation for details on format strings The first data parameter is the tick value as double an the second is tickUnitName as string. The following image shows an example for "y=%+.2f":
If this list contains items, this class will NOT plot a standard x-axis, but only mark the positions in this list. Every item is a x-position together with the label to be plotted there. The label may contain LaTeX markup.