2 * $Id: axis.h,v 1.46.2.3 2008/10/30 22:26:23 sfeam Exp $
7 * Copyright 2000, 2004 Thomas Williams, Colin Kelley
9 * Permission to use, copy, and distribute this software and its
10 * documentation for any purpose with or without fee is hereby granted,
11 * provided that the above copyright notice appear in all copies and
12 * that both that copyright notice and this permission notice appear
13 * in supporting documentation.
15 * Permission to modify the software is granted, but not the right to
16 * distribute the complete modified source code. Modifications are to
17 * be distributed as patches to the released version. Permission to
18 * distribute binaries produced by compiling modified sources is granted,
20 * 1. distribute the corresponding source modifications from the
21 * released version in the form of a patch file along with the binaries,
22 * 2. add special version identification to distinguish your version
23 * in addition to the base release version number,
24 * 3. provide your name and address as the primary contact for the
25 * support of your modified version, and
26 * 4. retain our contact information in regard to use of the base
28 * Permission to distribute the released version of the source code along
29 * with corresponding source modifications in the form of a patch file is
30 * granted with same provisions 2 through 4 for binary distributions.
32 * This software is provided "as is" without express or implied warranty
33 * to the extent permitted by applicable law.
36 #ifndef GNUPLOT_AXIS_H
37 #define GNUPLOT_AXIS_H
39 #include "gp_types.h" /* for TBOOLEAN */
42 #include "parse.h" /* for const_express() */
43 #include "tables.h" /* for the axis name parse table */
44 #include "term_api.h" /* for lp_style_type */
45 #include "util.h" /* for int_error() */
47 /* typedefs / #defines */
49 /* give some names to some array elements used in command.c and grap*.c
50 * maybe one day the relevant items in setshow will also be stored
53 * Always keep the following conditions alive:
54 * SECOND_X_AXIS = FIRST_X_AXIS + SECOND_AXES
55 * FIRST_X_AXIS & SECOND_AXES == 0
57 typedef enum AXIS_INDEX {
62 T_AXIS, /* fill gap */
64 SECOND_Z_AXIS, /* not used, yet */
67 R_AXIS, /* never used ? */
73 # define AXIS_ARRAY_SIZE 11
75 /* What kind of ticmarking is wanted? */
76 typedef enum en_ticseries_type {
77 TIC_COMPUTED=1, /* default; gnuplot figures them */
78 TIC_SERIES, /* user-defined series */
79 TIC_USER, /* user-defined points */
80 TIC_MONTH, /* print out month names ((mo-1)%12)+1 */
81 TIC_DAY /* print out day of week */
84 /* Defines one ticmark for TIC_USER style.
85 * If label==NULL, the value is printed with the usual format string.
86 * else, it is used as the format string (note that it may be a constant
87 * string, like "high" or "low").
89 typedef struct ticmark {
90 double position; /* where on axis is this */
91 char *label; /* optional (format) string label */
92 int level; /* 0=major tic, 1=minor tic */
93 struct ticmark *next; /* linked list */
96 /* Tic-mark labelling definition; see set xtics */
97 typedef struct ticdef {
98 t_ticseries_type type;
100 struct t_colorspec textcolor;
102 struct ticmark *user; /* for TIC_USER */
103 struct { /* for TIC_SERIES */
105 double end; /* ymax, if VERYLARGE */
107 TBOOLEAN mix; /* TRUE to use both the above */
109 struct position offset;
110 TBOOLEAN rangelimited; /* Limit tics to data range */
113 /* we want two auto modes for minitics - default where minitics are
114 * auto for log/time and off for linear, and auto where auto for all
115 * graphs I've done them in this order so that logscale-mode can
116 * simply test bit 0 to see if it must do the minitics automatically.
117 * similarly, conventional plot can test bit 1 to see if minitics are
119 enum en_minitics_status {
126 /* Function pointer type for callback functions doing operations for a
128 typedef void (*tic_callback) __PROTO((AXIS_INDEX, double, char *, struct lp_style_type ));
130 /* Values to put in the axis_tics[] variables that decides where the
131 * ticmarks should be drawn: not at all, on one or both plot borders,
132 * or the zeroaxes. These look like a series of values, but TICS_MASK
133 * shows that they're actually bit masks --> don't turn into an enum
136 #define TICS_ON_BORDER 1
137 #define TICS_ON_AXIS 2
139 #define TICS_MIRROR 4
142 #if 0 /* HBB 20010806 --- move GRID flags into axis struct */
143 /* Need to allow user to choose grid at first and/or second axes tics.
144 * Also want to let user choose circles at x or y tics for polar grid.
145 * Also want to allow user rectangular grid for polar plot or polar
146 * grid for parametric plot. So just go for full configurability.
150 #define GRID_X (1<<0)
151 #define GRID_Y (1<<1)
152 #define GRID_Z (1<<2)
153 #define GRID_X2 (1<<3)
154 #define GRID_Y2 (1<<4)
155 #define GRID_MX (1<<5)
156 #define GRID_MY (1<<6)
157 #define GRID_MZ (1<<7)
158 #define GRID_MX2 (1<<8)
159 #define GRID_MY2 (1<<9)
160 #define GRID_CB (1<<10)
161 #define GRID_MCB (1<<11)
164 /* HBB 20010610: new type for storing autoscale activity. Effectively
165 * two booleans (bits) in a single variable, so I'm using an enum with
166 * all 4 possible bit masks given readable names. */
167 typedef enum e_autoscale {
169 AUTOSCALE_MIN = 1<<0,
170 AUTOSCALE_MAX = 1<<1,
171 AUTOSCALE_BOTH = (1<<0 | 1 << 1),
172 AUTOSCALE_FIXMIN = 1<<2,
173 AUTOSCALE_FIXMAX = 1<<3
177 /* FIXME 20000725: collect some of those various TBOOLEAN fields into
178 * a larger int (or -- shudder -- a bitfield?) */
179 typedef struct axis {
180 /* range of this axis */
181 t_autoscale autoscale; /* Which end(s) are autoscaled? */
182 t_autoscale set_autoscale; /* what does 'set' think autoscale to be? */
183 int range_flags; /* flag bits about autoscale/writeback: */
184 /* write auto-ed ranges back to variables for autoscale */
185 #define RANGE_WRITEBACK 1
186 /* allow auto and reversed ranges */
187 #define RANGE_REVERSE 2
188 TBOOLEAN range_is_reverted; /* range [high:low] silently reverted? */
189 double min; /* 'transient' axis extremal values */
191 double set_min; /* set/show 'permanent' values */
193 double writeback_min; /* ULIG's writeback implementation */
194 double writeback_max;
195 double data_min; /* Not necessarily the same as axis min */
198 /* output-related quantities */
199 int term_lower; /* low and high end of the axis on output, */
200 int term_upper; /* ... (in terminal coordinates)*/
201 double term_scale; /* scale factor: plot --> term coords */
202 unsigned int term_zero; /* position of zero axis */
204 /* log axis control */
205 TBOOLEAN log; /* log axis stuff: flag "islog?" */
206 double base; /* logarithm base value */
207 double log_base; /* ln(base), for easier computations */
209 /* time/date axis control */
210 TBOOLEAN is_timedata; /* is this a time/date axis? */
211 TBOOLEAN format_is_numeric; /* format string looks like numeric??? */
212 char timefmt[MAX_ID_LEN+1]; /* format string for input */
213 char formatstring[MAX_ID_LEN+1];
214 /* the format string for output */
216 /* ticmark control variables */
217 int ticmode; /* tics on border/axis? mirrored? */
218 struct ticdef ticdef; /* tic series definition */
219 int tic_rotate; /* ticmarks rotated by this angle */
220 TBOOLEAN gridmajor; /* Grid lines wanted on major tics? */
221 TBOOLEAN gridminor; /* Grid lines for minor tics? */
222 int minitics; /* minor tic mode (none/auto/user)? */
223 double mtic_freq; /* minitic stepsize */
224 double ticscale; /* scale factor for tic marks (was (0..1])*/
225 double miniticscale; /* and for minitics */
226 TBOOLEAN tic_in; /* tics to be drawn inward? */
228 /* other miscellaneous fields */
229 text_label label; /* label string and position offsets */
230 lp_style_type zeroaxis; /* drawing style for zeroaxis, if any */
233 #define DEFAULT_AXIS_TICDEF {TIC_COMPUTED, NULL, {TC_DEFAULT, 0, 0}, {NULL, {0,0}, FALSE}, { character, character, character, 0., 0., 0. }, FALSE }
234 # define DEFAULT_AXIS_ZEROAXIS {0, -3, 0, 1.0, 1.0, 0}
236 #define DEFAULT_AXIS_STRUCT { \
237 AUTOSCALE_BOTH, AUTOSCALE_BOTH, /* auto, set_auto */ \
238 0, FALSE, /* range_flags, rev_range */ \
239 -10.0, 10.0, /* 3 pairs of min/max for axis itself */ \
242 0.0, 0.0, /* and another min/max for the data */ \
243 0, 0, 0, 0, /* terminal dependents */ \
244 FALSE, 0.0, 0.0, /* log, base, log(base) */ \
245 0, 1, /* is_timedata, format_numeric */ \
246 DEF_FORMAT, TIMEFMT, /* output format, timefmt */ \
247 NO_TICS, /* tic output positions (border, mirror) */ \
248 DEFAULT_AXIS_TICDEF, /* tic series definition */ \
249 0, FALSE, FALSE, /* tic_rotate, grid{major,minor} */ \
250 MINI_DEFAULT, 10, /* minitics, mtic_freq */ \
251 1.0, 0.5, TRUE, /* ticscale, miniticscale, tic_in */ \
252 EMPTY_LABELSTRUCT, /* axis label */ \
253 DEFAULT_AXIS_ZEROAXIS /* zeroaxis line style */ \
256 /* Table of default behaviours --- a subset of the struct above. Only
257 * those fields are present that differ from axis to axis. */
258 typedef struct axis_defaults {
259 double min; /* default axis endpoints */
261 char name[4]; /* axis name, like in "x2" or "t" */
262 int ticmode; /* tics on border/axis? mirrored? */
267 /* global variables in axis.c */
269 extern AXIS axis_array[AXIS_ARRAY_SIZE];
270 extern const AXIS_DEFAULTS axis_defaults[AXIS_ARRAY_SIZE];
272 /* A parsing table for mapping axis names into axis indices. For use
273 * by the set/show machinery, mainly */
274 extern const struct gen_table axisname_tbl[AXIS_ARRAY_SIZE+1];
277 extern const struct ticdef default_axis_ticdef;
279 /* default format for tic mark labels */
280 #define DEF_FORMAT "% g"
282 /* default parse timedata string */
283 #define TIMEFMT "%d/%m/%y,%H:%M"
286 extern const text_label default_axis_label;
288 /* zeroaxis linetype (flag type==-3 if none wanted) */
289 extern const lp_style_type default_axis_zeroaxis;
291 /* default grid linetype, to be used by 'unset grid' and 'reset' */
292 extern const struct lp_style_type default_grid_lp;
294 /* grid layer: -1 default, 0 back, 1 front */
295 extern int grid_layer;
297 /* global variables for communication with the tic callback functions */
298 /* FIXME HBB 20010806: had better be collected into a struct that's
299 * passed to the callback */
300 extern int tic_start, tic_direction, tic_mirror;
301 /* These are for passing on to write_multiline(): */
302 extern int tic_text, rotate_tics, tic_hjust, tic_vjust;
303 /* The remaining ones are for grid drawing; controlled by 'set grid': */
304 /* extern int grid_selection; --- comm'ed out, HBB 20010806 */
305 extern struct lp_style_type grid_lp; /* linestyle for major grid lines */
306 extern struct lp_style_type mgrid_lp; /* linestyle for minor grid lines */
307 extern double polar_grid_angle; /* angle step in polar grid in radians */
309 /* Length of the longest tics label, set by widest_tic_callback(): */
310 extern int widest_tic_strlen;
312 /* axes being used by the current plot */
313 extern AXIS_INDEX x_axis, y_axis, z_axis;
314 /* macros to reduce code clutter caused by the array notation, mainly
315 * in graphics.c and fit.c */
316 #define X_AXIS axis_array[x_axis]
317 #define Y_AXIS axis_array[y_axis]
318 #define Z_AXIS axis_array[z_axis]
319 #define CB_AXIS axis_array[COLOR_AXIS]
321 /* -------- macros using these variables: */
323 /* Macros to map from user to terminal coordinates and back */
324 #define AXIS_MAP(axis, variable) \
325 (int) ((axis_array[axis].term_lower) \
326 + ((variable) - axis_array[axis].min) \
327 * axis_array[axis].term_scale + 0.5)
328 #define AXIS_MAPBACK(axis, pos) \
329 (((double)(pos)-axis_array[axis].term_lower)/axis_array[axis].term_scale \
330 + axis_array[axis].min)
332 /* these are the old names for these: */
333 #define map_x(x) AXIS_MAP(x_axis, x)
334 #define map_y(y) AXIS_MAP(y_axis, y)
336 #define AXIS_SETSCALE(axis, out_low, out_high) \
337 axis_array[axis].term_scale = ((out_high) - (out_low)) \
338 / (axis_array[axis].max - axis_array[axis].min)
340 /* write current min/max_array contents into the set/show status
342 #define AXIS_WRITEBACK(axis) \
344 AXIS *this = axis_array + axis; \
346 if (this->range_flags & RANGE_WRITEBACK) { \
347 if (this->autoscale & AUTOSCALE_MIN) \
348 this->set_min = this->min; \
349 if (this->autoscale & AUTOSCALE_MAX) \
350 this->set_max = this->max; \
354 /* HBB 20000430: New macros, logarithmize a value into a stored
356 #define AXIS_DO_LOG(axis,value) (log(value) / axis_array[axis].log_base)
357 #define AXIS_UNDO_LOG(axis,value) exp((value) * axis_array[axis].log_base)
359 /* HBB 20000430: same, but these test if the axis is log, first: */
360 #define AXIS_LOG_VALUE(axis,value) \
361 (axis_array[axis].log ? AXIS_DO_LOG(axis,value) : (value))
362 #define AXIS_DE_LOG_VALUE(axis,coordinate) \
363 (axis_array[axis].log ? AXIS_UNDO_LOG(axis,coordinate): (coordinate))
366 /* copy scalar data to arrays. The difference between 3D and 2D
367 * versions is: dont know we have to support ranges [10:-10] - lets
368 * reverse it for now, then fix it at the end. */
369 /* FIXME HBB 20000426: unknown if this distinction makes any sense... */
370 #define AXIS_INIT3D(axis, islog_override, infinite) \
372 AXIS *this = axis_array + axis; \
374 this->autoscale = this->set_autoscale; \
375 if ((this->autoscale & AUTOSCALE_BOTH) == AUTOSCALE_NONE \
376 && this->set_max < this->set_min) { \
377 this->min = this->set_max; \
378 this->max = this->set_min; \
379 /* we will fix later */ \
381 this->min = (infinite && (this->set_autoscale & AUTOSCALE_MIN)) \
382 ? VERYLARGE : this->set_min; \
383 this->max = (infinite && (this->set_autoscale & AUTOSCALE_MAX)) \
384 ? -VERYLARGE : this->set_max; \
386 if (islog_override) { \
389 this->log_base = 0; \
391 this->log_base = this->log ? log(this->base) : 0; \
393 this->data_min = VERYLARGE; \
394 this->data_max = -VERYLARGE; \
397 #define AXIS_INIT2D(axis, infinite) \
399 AXIS *this = axis_array + axis; \
401 this->autoscale = this->set_autoscale; \
402 this->min = (infinite && (this->set_autoscale & AUTOSCALE_MIN)) \
403 ? VERYLARGE : this->set_min; \
404 this->max = (infinite && (this->set_autoscale & AUTOSCALE_MAX)) \
405 ? -VERYLARGE : this->set_max; \
406 this->log_base = this->log ? log(this->base) : 0; \
407 this->data_min = VERYLARGE; \
408 this->data_max = -VERYLARGE; \
411 /* handle reversed ranges */
412 #define CHECK_REVERSE(axis) do { \
413 AXIS *this = axis_array + axis; \
415 if (((this->autoscale & AUTOSCALE_BOTH) == AUTOSCALE_NONE) \
416 && (this->max < this->min)) { \
417 double temp = this->min; \
419 this->min = this->max; \
421 this->range_is_reverted = 1; \
423 this->range_is_reverted = (this->range_flags & RANGE_REVERSE); \
426 /* HBB NEW 20050316: macros to always access the actual minimum, even
427 * if 'set view map' or something else flipped things around behind
429 #define AXIS_ACTUAL_MIN(axis) \
430 (axis_array[axis].range_flags & RANGE_REVERSE \
431 ? axis_array[axis].max : axis_array[axis].min)
433 #define AXIS_ACTUAL_MAX(axis) \
434 (axis_array[axis].range_flags & RANGE_REVERSE \
435 ? axis_array[axis].min : axis_array[axis].max)
437 /* HBB 20000725: new macro, built upon ULIG's SAVE_WRITEBACK(axis),
438 * but easier to use. Code like this occured twice, in plot2d and
440 #define SAVE_WRITEBACK_ALL_AXES \
444 for (axis = 0; axis < AXIS_ARRAY_SIZE; axis++) \
445 if(axis_array[axis].range_flags & RANGE_WRITEBACK) { \
446 set_writeback_min(axis); \
447 set_writeback_max(axis); \
451 /* get optional [min:max] */
452 #define PARSE_RANGE(axis) \
454 if (equals(c_token, "[")) { \
456 axis_array[axis].autoscale = \
457 load_range(axis, &axis_array[axis].min, &axis_array[axis].max, \
458 axis_array[axis].autoscale); \
459 if (!equals(c_token, "]")) \
460 int_error(c_token, "']' expected"); \
465 /* HBB 20000430: new macro, like PARSE_RANGE, but for named ranges as
466 * in 'plot [phi=3.5:7] sin(phi)' */
467 #define PARSE_NAMED_RANGE(axis, dummy_token) \
469 if (equals(c_token, "[")) { \
471 if (isletter(c_token)) { \
472 if (equals(c_token + 1, "=")) { \
473 dummy_token = c_token; \
476 /* oops; probably an expression with a variable: act \
477 * as if no variable name had been seen, by \
480 axis_array[axis].autoscale = load_range(axis, &axis_array[axis].min, \
481 &axis_array[axis].max, \
482 axis_array[axis].autoscale); \
483 if (!equals(c_token, "]")) \
484 int_error(c_token, "']' expected"); \
489 /* parse a position of the form
490 * [coords] x, [coords] y {,[coords] z}
491 * where coords is one of first,second.graph,screen,character
492 * if first or second, we need to take axis_is_timedata into account
494 #define GET_NUMBER_OR_TIME(store,axes,axis) \
496 if (((axes) >= 0) && (axis_array[(axes)+(axis)].is_timedata) \
497 && isstringvalue(c_token)) { \
499 char *ss = try_to_get_string(); \
500 if (gstrptime(ss,axis_array[axis].timefmt,&tm)) \
501 (store) = (double) gtimegm(&tm); \
504 struct value value; \
505 (store) = real(const_express(&value)); \
509 /* This is one is very similar to GET_NUMBER_OR_TIME, but has slightly
510 * different usage: it writes out '0' in case of inparsable time data,
511 * and it's used when the target axis is fixed without a 'first' or
512 * 'second' keyword in front of it. */
513 #define GET_NUM_OR_TIME(store,axis) \
516 GET_NUMBER_OR_TIME(store, FIRST_AXES, axis); \
519 /* store VALUE or log(VALUE) in STORE, set TYPE as appropriate
520 * Do OUT_ACTION or UNDEF_ACTION as appropriate
521 * adjust range provided type is INRANGE (ie dont adjust y if x is outrange
522 * VALUE must not be same as STORE
523 * Note: see the particular implementation for COLOR AXIS below.
526 #define STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, TYPE, AXIS, \
527 OUT_ACTION, UNDEF_ACTION) \
529 /* HBB 20000726: new check, to avoid crashes with axis index -1 */ \
532 /* HBB 20040304: new check to avoid storing infinities and NaNs */ \
533 if (! (VALUE > -VERYLARGE && VALUE < VERYLARGE)) { \
538 if (axis_array[AXIS].log) { \
543 } else if (VALUE == 0.0) { \
544 STORE = -VERYLARGE; \
549 STORE = AXIS_DO_LOG(AXIS,VALUE); \
553 if (TYPE != INRANGE) \
554 break; /* don't set y range if x is outrange, for example */ \
556 break; /* HBB 20000507: don't check range if not a coordinate */ \
557 if ( VALUE<axis_array[AXIS].data_min ) \
558 axis_array[AXIS].data_min = VALUE; \
559 if ( VALUE<axis_array[AXIS].min ) { \
560 if (axis_array[AXIS].autoscale & AUTOSCALE_MIN) \
561 axis_array[AXIS].min = VALUE; \
568 if ( VALUE>axis_array[AXIS].data_max ) \
569 axis_array[AXIS].data_max = VALUE; \
570 if ( VALUE>axis_array[AXIS].max ) { \
571 if (axis_array[AXIS].autoscale & AUTOSCALE_MAX) \
572 axis_array[AXIS].max = VALUE; \
580 /* Implementation of the above for the color axis. It should not change
581 * the type of the point (out-of-range color is plotted with the color
582 * of the min or max color value).
584 #define COLOR_STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, TYPE, AXIS, \
585 OUT_ACTION, UNDEF_ACTION) \
587 int c_type_tmp = TYPE; \
588 STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, c_type_tmp, AXIS, \
589 OUT_ACTION, UNDEF_ACTION); \
592 /* Empty macro arguments triggered NeXT cpp bug */
593 /* #define NOOP (0) caused many warnings from gcc 3.2 */
594 /* Now trying ((void)0) */
595 #define NOOP ((void)0)
597 /* HBB 20000506: new macro, initializes one variable to the same
598 * value, for all axes. */
599 #define INIT_AXIS_ARRAY(field, value) \
602 for (tmp=0; tmp<AXIS_ARRAY_SIZE; tmp++) \
603 axis_array[tmp].field=(value); \
606 /* HBB 20000506: new macro to automatically build intializer lists
607 * for arrays of AXIS_ARRAY_SIZE equal elements */
608 #define AXIS_ARRAY_INITIALIZER(value) { \
609 value, value, value, value, value, \
610 value, value, value, value, value, value }
613 #define SET_DEFFORMAT(axis, flag_array) \
614 if (flag_array[axis]) { \
615 (void) strcpy(axis_array[axis].formatstring,DEF_FORMAT); \
616 axis_array[axis].format_is_numeric = 1; \
620 /* 'roundoff' check tolerance: less than one hundredth of a tic mark */
621 #define SIGNIF (0.01)
622 /* (DFK) Watch for cancellation error near zero on axes labels */
623 /* FIXME HBB 20000521: these seem not to be used much, anywhere... */
624 #define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x))
627 /* ------------ functions exported by axis.c */
628 t_autoscale load_range __PROTO((AXIS_INDEX, double *, double *, t_autoscale));
629 void axis_unlog_interval __PROTO((AXIS_INDEX, double *, double *, TBOOLEAN));
630 void axis_revert_and_unlog_range __PROTO((AXIS_INDEX));
631 double axis_log_value_checked __PROTO((AXIS_INDEX, double, const char *));
632 void axis_checked_extend_empty_range __PROTO((AXIS_INDEX, const char *mesg));
633 char * copy_or_invent_formatstring __PROTO((AXIS_INDEX));
634 double quantize_normal_tics __PROTO((double, int));
635 void setup_tics __PROTO((AXIS_INDEX, int));
636 void gen_tics __PROTO((AXIS_INDEX, /* int, */ tic_callback));
637 void axis_output_tics __PROTO((AXIS_INDEX, int *, AXIS_INDEX, tic_callback));
638 void axis_set_graphical_range __PROTO((AXIS_INDEX, unsigned int lower, unsigned int upper));
639 void axis_draw_2d_zeroaxis __PROTO((AXIS_INDEX, AXIS_INDEX));
640 TBOOLEAN some_grid_selected __PROTO((void));
641 void add_tic_user __PROTO((AXIS_INDEX, char *, double, int));
643 double get_writeback_min __PROTO((AXIS_INDEX));
644 double get_writeback_max __PROTO((AXIS_INDEX));
645 void set_writeback_min __PROTO((AXIS_INDEX));
646 void set_writeback_max __PROTO((AXIS_INDEX));
648 /* set widest_tic_label: length of the longest tics label */
649 void widest_tic_callback __PROTO((AXIS_INDEX, double place, char *text, struct lp_style_type grid));
651 void get_position __PROTO((struct position *pos));
652 void get_position_default __PROTO((struct position *pos, enum position_type default_type));
654 /* ------------ autoscaling of the color axis */
655 #define NEED_PALETTE(plot) \
656 (PM3DSURFACE == (plot)->plot_style \
657 || PM3D_IMPLICIT == pm3d.implicit \
658 || 1 == (plot)->lp_properties.use_palette)
659 int set_cbminmax __PROTO((void));
661 #endif /* GNUPLOT_AXIS_H */