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