1 //      plshade demo, using color fill.
2 //
3 //      Maurice LeBrun
4 //      IFS, University of Texas at Austin
5 //      20 Mar 1994
6 //
7 
8 #include "plcdemos.h"
9 
10 // Fundamental settings.  See notes[] for more info.
11 
12 static int ns      = 20;        // Default number of shade levels
13 static int nx      = 35;        // Default number of data points in x
14 static int ny      = 46;        // Default number of data points in y
15 static int exclude = 0;         // By default do not plot a page illustrating
16                                 // exclusion.  API is probably going to change
17                                 // anyway, and cannot be reproduced by any
18                                 // front end other than the C one.
19 
20 // For now, don't show the colorbars while we are working out the API.
21 static int colorbar = 1;
22 
23 // polar plot data
24 #define PERIMETERPTS    100
25 
26 // Transformation function
27 
28 PLFLT tr[6];
29 
30 static void
mypltr(PLFLT x,PLFLT y,PLFLT * tx,PLFLT * ty,void * PL_UNUSED (pltr_data))31 mypltr( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void * PL_UNUSED( pltr_data ) )
32 {
33     *tx = tr[0] * x + tr[1] * y + tr[2];
34     *ty = tr[3] * x + tr[4] * y + tr[5];
35 }
36 
37 // Function prototypes
38 
39 static void
40 f2mnmx( PLFLT **f, PLINT nx, PLINT ny, PLFLT *fmin, PLFLT *fmax );
41 
42 PLINT zdefined( PLFLT x, PLFLT y );
43 
44 // Options data structure definition.
45 
46 static PLOptionTable options[] = {
47     {
48         "colorbar",              // Turns on the colorbar for each page
49         NULL,
50         NULL,
51         &colorbar,
52         PL_OPT_BOOL,
53         "-colorbar",
54         "Plot a \"color bar\" on each page."
55     },
56     {
57         "exclude",              // Turns on page showing exclusion
58         NULL,
59         NULL,
60         &exclude,
61         PL_OPT_BOOL,
62         "-exclude",
63         "Plot the \"exclusion\" page."
64     },
65     {
66         "ns",                   // Number of shade levels
67         NULL,
68         NULL,
69         &ns,
70         PL_OPT_INT,
71         "-ns levels",
72         "Sets number of shade levels"
73     },
74     {
75         "nx",                   // Number of data points in x
76         NULL,
77         NULL,
78         &nx,
79         PL_OPT_INT,
80         "-nx xpts",
81         "Sets number of data points in x"
82     },
83     {
84         "ny",                   // Number of data points in y
85         NULL,
86         NULL,
87         &ny,
88         PL_OPT_INT,
89         "-ny ypts",
90         "Sets number of data points in y"
91     },
92     {
93         NULL,                   // option
94         NULL,                   // handler
95         NULL,                   // client data
96         NULL,                   // address of variable to set
97         0,                      // mode flag
98         NULL,                   // short syntax
99         NULL
100     }                           // long syntax
101 };
102 
103 static PLCHAR_VECTOR notes[] = {
104     "To get smoother color variation, increase ns, nx, and ny.  To get faster",
105     "response (especially on a serial link), decrease them.  A decent but quick",
106     "test results from ns around 5 and nx, ny around 25.",
107     NULL
108 };
109 
110 PLINT
zdefined(PLFLT x,PLFLT y)111 zdefined( PLFLT x, PLFLT y )
112 {
113     PLFLT z = sqrt( x * x + y * y );
114 
115     return z < 0.4 || z > 0.6;
116 }
117 
118 
119 
120 //--------------------------------------------------------------------------
121 // main
122 //
123 // Does several shade plots using different coordinate mappings.
124 //--------------------------------------------------------------------------
125 
126 int
main(int argc,char * argv[])127 main( int argc, char *argv[] )
128 {
129     int           i, j;
130     PLFLT         x, y, argx, argy, distort, r, t;
131     PLFLT         px[PERIMETERPTS], py[PERIMETERPTS];
132 
133     PLFLT         **z, **w, zmin, zmax;
134     PLFLT         *clevel, *shedge, *xg1, *yg1;
135     PLcGrid       cgrid1;
136     PLcGrid2      cgrid2;
137 
138     PLFLT         fill_width = 2., cont_width = 0.;
139     PLFLT         colorbar_width, colorbar_height;
140     PLINT         cont_color = 0;
141 #define NUM_AXES    1
142     PLINT         n_axis_opts = NUM_AXES;
143     PLCHAR_VECTOR axis_opts[] = {
144         "bcvtm",
145     };
146     PLINT         num_values[NUM_AXES];
147     PLFLT         *values[NUM_AXES];
148     PLFLT         axis_ticks[NUM_AXES] = {
149         0.0,
150     };
151     PLINT         axis_subticks[NUM_AXES] = {
152         0,
153     };
154 #define NUM_LABELS    1
155     PLINT         n_labels     = NUM_LABELS;
156     PLINT         label_opts[] = {
157         PL_COLORBAR_LABEL_BOTTOM,
158     };
159     PLCHAR_VECTOR labels[] = {
160         "Magnitude",
161     };
162 
163 // Parse and process command line arguments
164 
165     plMergeOpts( options, "x16c options", notes );
166     plparseopts( &argc, argv, PL_PARSE_FULL );
167 
168 // Load colour palettes
169     plspal0( "cmap0_black_on_white.pal" );
170     plspal1( "cmap1_gray.pal", 1 );
171 // Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
172     plscmap0n( 3 );
173 // Initialize plplot
174 
175     plinit();
176 
177 // Set up transformation function
178 
179     tr[0] = 2. / ( nx - 1 );
180     tr[1] = 0.0;
181     tr[2] = -1.0;
182     tr[3] = 0.0;
183     tr[4] = 2. / ( ny - 1 );
184     tr[5] = -1.0;
185 
186 // Allocate data structures
187 
188     clevel = (PLFLT *) calloc( (size_t) ns, sizeof ( PLFLT ) );
189     shedge = (PLFLT *) calloc( (size_t) ( ns + 1 ), sizeof ( PLFLT ) );
190     xg1    = (PLFLT *) calloc( (size_t) nx, sizeof ( PLFLT ) );
191     yg1    = (PLFLT *) calloc( (size_t) ny, sizeof ( PLFLT ) );
192 
193     plAlloc2dGrid( &z, nx, ny );
194     plAlloc2dGrid( &w, nx, ny );
195 
196 // Set up data array
197 
198     for ( i = 0; i < nx; i++ )
199     {
200         x = (PLFLT) ( i - ( nx / 2 ) ) / (PLFLT) ( nx / 2 );
201         for ( j = 0; j < ny; j++ )
202         {
203             y = (PLFLT) ( j - ( ny / 2 ) ) / (PLFLT) ( ny / 2 ) - 1.0;
204 
205             z[i][j] = -sin( 7. * x ) * cos( 7. * y ) + x * x - y * y;
206             w[i][j] = -cos( 7. * x ) * sin( 7. * y ) + 2 * x * y;
207         }
208     }
209     f2mnmx( z, nx, ny, &zmin, &zmax );
210     for ( i = 0; i < ns; i++ )
211         clevel[i] = zmin + ( zmax - zmin ) * ( i + 0.5 ) / (PLFLT) ns;
212 
213     for ( i = 0; i < ns + 1; i++ )
214         shedge[i] = zmin + ( zmax - zmin ) * (PLFLT) i / (PLFLT) ns;
215 
216 // Set up coordinate grids
217 
218     cgrid1.xg = xg1;
219     cgrid1.yg = yg1;
220     cgrid1.nx = nx;
221     cgrid1.ny = ny;
222 
223     plAlloc2dGrid( &cgrid2.xg, nx, ny );
224     plAlloc2dGrid( &cgrid2.yg, nx, ny );
225     cgrid2.nx = nx;
226     cgrid2.ny = ny;
227 
228     for ( i = 0; i < nx; i++ )
229     {
230         for ( j = 0; j < ny; j++ )
231         {
232             mypltr( (PLFLT) i, (PLFLT) j, &x, &y, NULL );
233 
234             argx    = x * M_PI / 2;
235             argy    = y * M_PI / 2;
236             distort = 0.4;
237 
238             cgrid1.xg[i] = x + distort * cos( argx );
239             cgrid1.yg[j] = y - distort * cos( argy );
240 
241             cgrid2.xg[i][j] = x + distort * cos( argx ) * cos( argy );
242             cgrid2.yg[i][j] = y - distort * cos( argx ) * cos( argy );
243         }
244     }
245 
246 // Plot using identity transform
247 
248     pladv( 0 );
249     plvpor( 0.1, 0.9, 0.1, 0.9 );
250     plwind( -1.0, 1.0, -1.0, 1.0 );
251 
252     plpsty( 0 );
253 
254     plshades( (PLFLT_MATRIX) z, nx, ny, NULL, -1., 1., -1., 1.,
255         shedge, ns + 1, fill_width,
256         cont_color, cont_width,
257         plfill, 1, NULL, NULL );
258 
259     if ( colorbar )
260     {
261         // Smaller text
262         plschr( 0.0, 0.75 );
263         // Small ticks on the vertical axis
264         plsmaj( 0.0, 0.5 );
265         plsmin( 0.0, 0.5 );
266 
267         num_values[0] = ns + 1;
268         values[0]     = shedge;
269         plcolorbar( &colorbar_width, &colorbar_height,
270             PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
271             0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
272             cont_color, cont_width,
273             n_labels, label_opts, labels,
274             n_axis_opts, axis_opts,
275             axis_ticks, axis_subticks,
276             num_values, (PLFLT_MATRIX) values );
277 
278         // Reset text and tick sizes
279         plschr( 0.0, 1.0 );
280         plsmaj( 0.0, 1.0 );
281         plsmin( 0.0, 1.0 );
282     }
283 
284     plcol0( 1 );
285     plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
286     plcol0( 2 );
287 //
288 //  plcont((const PLFLT **) w, nx, ny, 1, nx, 1, ny, clevel, ns, mypltr, NULL);
289 //
290     pllab( "distance", "altitude", "Bogon density" );
291 
292 // Plot using 1d coordinate transform
293 
294 // Load colour palettes
295     plspal0( "cmap0_black_on_white.pal" );
296     plspal1( "cmap1_blue_yellow.pal", 1 );
297 // Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
298     plscmap0n( 3 );
299 
300     pladv( 0 );
301     plvpor( 0.1, 0.9, 0.1, 0.9 );
302     plwind( -1.0, 1.0, -1.0, 1.0 );
303 
304     plpsty( 0 );
305 
306     plshades( (PLFLT_MATRIX) z, nx, ny, NULL, -1., 1., -1., 1.,
307         shedge, ns + 1, fill_width,
308         cont_color, cont_width,
309         plfill, 1, pltr1, (void *) &cgrid1 );
310 
311     if ( colorbar )
312     {
313         // Smaller text
314         plschr( 0.0, 0.75 );
315         // Small ticks on the vertical axis
316         plsmaj( 0.0, 0.5 );
317         plsmin( 0.0, 0.5 );
318 
319         num_values[0] = ns + 1;
320         values[0]     = shedge;
321         plcolorbar( &colorbar_width, &colorbar_height,
322             PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
323             0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
324             cont_color, cont_width,
325             n_labels, label_opts, labels,
326             n_axis_opts, axis_opts,
327             axis_ticks, axis_subticks,
328             num_values, (PLFLT_MATRIX) values );
329 
330         // Reset text and tick sizes
331         plschr( 0.0, 1.0 );
332         plsmaj( 0.0, 1.0 );
333         plsmin( 0.0, 1.0 );
334     }
335 
336     plcol0( 1 );
337     plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
338     plcol0( 2 );
339 //
340 //  plcont((const PLFLT **) w, nx, ny, 1, nx, 1, ny, clevel, ns, pltr1, (void *) &cgrid1);
341 //
342     pllab( "distance", "altitude", "Bogon density" );
343 
344 // Plot using 2d coordinate transform
345 
346 // Load colour palettes
347     plspal0( "cmap0_black_on_white.pal" );
348     plspal1( "cmap1_blue_red.pal", 1 );
349 // Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
350     plscmap0n( 3 );
351 
352     pladv( 0 );
353     plvpor( 0.1, 0.9, 0.1, 0.9 );
354     plwind( -1.0, 1.0, -1.0, 1.0 );
355 
356     plpsty( 0 );
357 
358     plshades( (PLFLT_MATRIX) z, nx, ny, NULL, -1., 1., -1., 1.,
359         shedge, ns + 1, fill_width,
360         cont_color, cont_width,
361         plfill, 0, pltr2, (void *) &cgrid2 );
362 
363     if ( colorbar )
364     {
365         // Smaller text
366         plschr( 0.0, 0.75 );
367         // Small ticks on the vertical axis
368         plsmaj( 0.0, 0.5 );
369         plsmin( 0.0, 0.5 );
370 
371         num_values[0] = ns + 1;
372         values[0]     = shedge;
373         plcolorbar( &colorbar_width, &colorbar_height,
374             PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
375             0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
376             cont_color, cont_width,
377             n_labels, label_opts, labels,
378             n_axis_opts, axis_opts,
379             axis_ticks, axis_subticks,
380             num_values, (PLFLT_MATRIX) values );
381 
382         // Reset text and tick sizes
383         plschr( 0.0, 1.0 );
384         plsmaj( 0.0, 1.0 );
385         plsmin( 0.0, 1.0 );
386     }
387 
388     plcol0( 1 );
389     plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
390     plcol0( 2 );
391     plcont( (PLFLT_MATRIX) w, nx, ny, 1, nx, 1, ny, clevel, ns, pltr2, (void *) &cgrid2 );
392 
393     pllab( "distance", "altitude", "Bogon density, with streamlines" );
394 
395 // Plot using 2d coordinate transform
396 
397 // Load colour palettes
398     plspal0( "" );
399     plspal1( "", 1 );
400 // Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
401     plscmap0n( 3 );
402 
403     pladv( 0 );
404     plvpor( 0.1, 0.9, 0.1, 0.9 );
405     plwind( -1.0, 1.0, -1.0, 1.0 );
406 
407     plpsty( 0 );
408 
409     plshades( (PLFLT_MATRIX) z, nx, ny, NULL, -1., 1., -1., 1.,
410         shedge, ns + 1, fill_width,
411         2, 3.,
412         plfill, 0, pltr2, (void *) &cgrid2 );
413 
414     if ( colorbar )
415     {
416         // Smaller text
417         plschr( 0.0, 0.75 );
418         // Small ticks on the vertical axis
419         plsmaj( 0.0, 0.5 );
420         plsmin( 0.0, 0.5 );
421 
422         num_values[0] = ns + 1;
423         values[0]     = shedge;
424         plcolorbar( &colorbar_width, &colorbar_height,
425             PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
426             0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
427             2, 3.,
428             n_labels, label_opts, labels,
429             n_axis_opts, axis_opts,
430             axis_ticks, axis_subticks,
431             num_values, (PLFLT_MATRIX) values );
432 
433         // Reset text and tick sizes
434         plschr( 0.0, 1.0 );
435         plsmaj( 0.0, 1.0 );
436         plsmin( 0.0, 1.0 );
437     }
438 
439     plcol0( 1 );
440     plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
441     plcol0( 2 );
442 //    plcont((const PLFLT **) w, nx, ny, 1, nx, 1, ny, clevel, ns, pltr2, (void *) &cgrid2);
443 
444     pllab( "distance", "altitude", "Bogon density" );
445 
446 // Note this exclusion API will probably change.
447 
448 // Plot using 2d coordinate transform and exclusion
449 
450     if ( exclude )
451     {
452 // Load colour palettes
453         plspal0( "cmap0_black_on_white.pal" );
454         plspal1( "cmap1_gray.pal", 1 );
455 // Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
456         plscmap0n( 3 );
457 
458         pladv( 0 );
459         plvpor( 0.1, 0.9, 0.1, 0.9 );
460         plwind( -1.0, 1.0, -1.0, 1.0 );
461 
462         plpsty( 0 );
463 
464         plshades( (PLFLT_MATRIX) z, nx, ny, zdefined, -1., 1., -1., 1.,
465             shedge, ns + 1, fill_width,
466             cont_color, cont_width,
467             plfill, 0, pltr2, (void *) &cgrid2 );
468 
469         plcol0( 1 );
470         plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
471 
472         pllab( "distance", "altitude", "Bogon density with exclusion" );
473     }
474 // Example with polar coordinates.
475 
476 // Load colour palettes
477     plspal0( "cmap0_black_on_white.pal" );
478     plspal1( "cmap1_gray.pal", 1 );
479 // Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
480     plscmap0n( 3 );
481 
482     pladv( 0 );
483     plvpor( .1, .9, .1, .9 );
484     plwind( -1., 1., -1., 1. );
485 
486 
487     plpsty( 0 );
488 
489     // Build new coordinate matrices.
490 
491     for ( i = 0; i < nx; i++ )
492     {
493         r = ( (PLFLT) i ) / ( nx - 1 );
494         for ( j = 0; j < ny; j++ )
495         {
496             t = ( 2. * M_PI / ( ny - 1. ) ) * j;
497             cgrid2.xg[i][j] = r * cos( t );
498             cgrid2.yg[i][j] = r * sin( t );
499             z[i][j]         = exp( -r * r ) * cos( 5. * M_PI * r ) * cos( 5. * t );
500         }
501     }
502 
503     // Need a new shedge to go along with the new data set.
504 
505     f2mnmx( z, nx, ny, &zmin, &zmax );
506 
507     for ( i = 0; i < ns + 1; i++ )
508         shedge[i] = zmin + ( zmax - zmin ) * (PLFLT) i / (PLFLT) ns;
509 
510     //  Now we can shade the interior region.
511     plshades( (PLFLT_MATRIX) z, nx, ny, NULL, -1., 1., -1., 1.,
512         shedge, ns + 1, fill_width,
513         cont_color, cont_width,
514         plfill, 0, pltr2, (void *) &cgrid2 );
515 
516     if ( colorbar )
517     {
518         // Smaller text
519         plschr( 0.0, 0.75 );
520         // Small ticks on the vertical axis
521         plsmaj( 0.0, 0.5 );
522         plsmin( 0.0, 0.5 );
523 
524         num_values[0] = ns + 1;
525         values[0]     = shedge;
526         plcolorbar( &colorbar_width, &colorbar_height,
527             PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
528             0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
529             cont_color, cont_width,
530             n_labels, label_opts, labels,
531             n_axis_opts, axis_opts,
532             axis_ticks, axis_subticks,
533             num_values, (PLFLT_MATRIX) values );
534 
535         // Reset text and tick sizes
536         plschr( 0.0, 1.0 );
537         plsmaj( 0.0, 1.0 );
538         plsmin( 0.0, 1.0 );
539     }
540 
541 // Now we can draw the perimeter.  (If do before, shade stuff may overlap.)
542     for ( i = 0; i < PERIMETERPTS; i++ )
543     {
544         t     = ( 2. * M_PI / ( PERIMETERPTS - 1 ) ) * (PLFLT) i;
545         px[i] = cos( t );
546         py[i] = sin( t );
547     }
548     plcol0( 1 );
549     plline( PERIMETERPTS, px, py );
550 
551     // And label the plot.
552 
553     plcol0( 2 );
554     pllab( "", "", "Tokamak Bogon Instability" );
555 
556 
557 // Clean up
558 
559     free( (void *) clevel );
560     free( (void *) shedge );
561     free( (void *) xg1 );
562     free( (void *) yg1 );
563     plFree2dGrid( z, nx, ny );
564     plFree2dGrid( w, nx, ny );
565     plFree2dGrid( cgrid2.xg, nx, ny );
566     plFree2dGrid( cgrid2.yg, nx, ny );
567 
568     plend();
569 
570     exit( 0 );
571 }
572 
573 //--------------------------------------------------------------------------
574 // f2mnmx
575 //
576 // Returns min & max of input 2d array.
577 //--------------------------------------------------------------------------
578 
579 static void
f2mnmx(PLFLT ** f,PLINT nnx,PLINT nny,PLFLT * fnmin,PLFLT * fnmax)580 f2mnmx( PLFLT **f, PLINT nnx, PLINT nny, PLFLT *fnmin, PLFLT *fnmax )
581 {
582     int i, j;
583 
584     *fnmax = f[0][0];
585     *fnmin = *fnmax;
586 
587     for ( i = 0; i < nnx; i++ )
588     {
589         for ( j = 0; j < nny; j++ )
590         {
591             *fnmax = MAX( *fnmax, f[i][j] );
592             *fnmin = MIN( *fnmin, f[i][j] );
593         }
594     }
595 }
596