Dean Foster <
dean.foster@...> writes:
> If all calls to points go through the function AXIS_MAP and
> AXIS_UNMAP, then it does seem that we are pretty close to being able
> to do a late change of axis. I didn't know how to check that these
> functions were always used. (I'm mostly a C++ programmer--so my only
> tricks of making things private to find who peeks at data doesn't work
> here. But I'm sure someone else knows if these functions are always
> used as go-betweens.) I can try using them for my transformation and
> see if it seems to work.
>
> I've thought a bit about the same difficulties that you mentioned.
> Let me share some of my thoughts:
>
Ethan Merritt wrote:
> > - Unresolved issues:
> > + how to deal with singularities in the transform? We won't hit them until
> > we are in the middle of plotting.
...
> So my claim is, let the transformation deal with it and all the rest
> of the code has to do is check if the point is in range AFTER it has
> been transformed.
This works if the user has specified plot limits. However, the
autoscaling code should also check for undefined == TRUE or a nonzero
imaginary.
Ethan Merritt wrote:
> > + how to pass the transform to an external helper (gnuplot_x11) or wrap it
> > in the driver output (canvas terminal)?
Surely that interface, in both directions, can be in terminal coordinates?
> > + tic placement (although I can report that my quick hack "just worked" for
> > placing logscale tics on simple plots with no change to the tic code at all
>
> tic placement is an entirely factored from transformations. I think
> Jim Van Zandt's code makes lovely tics. So this is now a solved
> problem.
Thanks. A couple of caveats, though:
The current code for the probability transformation relies on having
an analytic inverse. There is code in there to do a numerical inverse
(see FITVAL in transform.c), but it's currently used only for tic
placement.
The numerical inverse works only for monotonic transforms. I don't
even want to think about non-monotonic transforms.
Currently, tic placement is the same for horizontal and vertical axes.
It ought to account for tic label size, and allow more tic marks on
vertical axes.
> I have been thinking a bit about this. I think that the core requirement
> is simply to store two function pointers for each axis: the transform and
> its inverse. The forward transform is used [only?] by the routines that
> map plot coordinates to terminal coordinates. It is conceptually easiest
> to show for the routine map_position_double():
We might go through three phases here. (1) implement only fixed
transforms for which we have analytic inverses, so the pointer could
be to a C function. (2) allow user-defined functions, but demand
that the user also supply the inverse function. Here we would need a
pointer to a parse table. (3) Allow the user to
omit the inverse function, falling back on the rational interpolation.
We could go through three similar phases for range checking: (1) only
fixed transforms, for which we can hard code the tests (as in
axis_log_value_checked() in axis.c, except we'd probably switch to
pointers to separate test functions), (2) Require the user to provide
a range checking function. Here we would need a pointer to a parse
table. (3) If the range checking function isn't supplied, fall back
on evaluating the transform and checking for "undefined". However,
this would not work for functions that require limits to become
monotonic. For example, I'd like to implement f(x)=1/x, so I could
label spectra in both energy and wavelength units. However, the range
requirement could be either "x>0" or "x<0", and if there are both
positive and negative values in the data, the program would be hard
pressed to make the right choice.
> I suggest to introduce a new command
> {un}set transform {x|y|x2|y2|...} func(dummy)
Well, currently we have "{un}set logscale {x|y...}" so maybe we should
use "scale" instead of (or in addition to) "transform". E.g. for
predefined transformations:
{un}set {log|linear|probability} scale {x|y...}
and for user supplied transformations
{un}set user scale {x|y...} func(dummy)
{unscale func2(dummy)}
{rangecheck func3(dummy)}
or maybe
{un}set user scale func({x|y...})
{unscale func2({x|y...})}
{rangecheck func3({x|y...})}
Of course "unset" means to use linear scaling.
- Jim Van Zandt
------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to:
http://p.sf.net/sfu/opensolaris-get_______________________________________________
gnuplot-beta mailing list
gnuplot-beta@...
https://lists.sourceforge.net/lists/listinfo/gnuplot-beta