@@ -22,11 +22,11 @@ module pyplot_module
22
22
character (len=* ), parameter :: tmp_file = ' pyplot_module_temp_1234567890.py' ! ! Default name of the temporary file
23
23
! ! (this can also be user-specified).
24
24
25
- character (len=* ), parameter :: python_exe = ' python' ! ! The python executable name.
26
- character (len=* ), parameter :: int_fmt = ' (I10)' ! ! integer format string
27
- integer , parameter :: max_int_len = 10 ! ! max string length for integers
28
- character (len=* ), parameter :: real_fmt = ' (E30.16)' ! ! real number format string
29
- integer , parameter :: max_real_len = 30 ! ! max string length for reals
25
+ character (len=* ), parameter :: python_exe = ' python' ! ! The python executable name.
26
+ character (len=* ), parameter :: int_fmt = ' (I10)' ! ! integer format string
27
+ integer , parameter :: max_int_len = 10 ! ! max string length for integers
28
+ character (len=* ), parameter :: real_fmt_default = ' (E30.16)' ! ! default real number format string
29
+ integer , parameter :: max_real_len = 30 ! ! max string length for reals
30
30
31
31
type, public :: pyplot
32
32
@@ -42,6 +42,8 @@ module pyplot_module
42
42
logical :: polar = .false. ! ! it is a polar plot
43
43
logical :: axis_equal = .false. ! ! equal scale on each axis
44
44
45
+ character (len= :),allocatable :: real_fmt ! ! real number formatting
46
+
45
47
contains
46
48
47
49
! public methods
@@ -73,7 +75,8 @@ subroutine destroy(me)
73
75
74
76
class(pyplot),intent (inout ) :: me ! ! pyplot handler
75
77
76
- if (allocated (me% str)) deallocate (me% str)
78
+ if (allocated (me% str)) deallocate (me% str)
79
+ if (allocated (me% real_fmt)) deallocate (me% real_fmt)
77
80
78
81
end subroutine destroy
79
82
! *****************************************************************************************
@@ -100,7 +103,7 @@ end subroutine add_str
100
103
101
104
subroutine initialize (me , grid , xlabel , ylabel , zlabel , title , legend , use_numpy , figsize , &
102
105
font_size , axes_labelsize , xtick_labelsize , ytick_labelsize , ztick_labelsize , &
103
- legend_fontsize , mplot3d , axis_equal , polar )
106
+ legend_fontsize , mplot3d , axis_equal , polar , real_fmt )
104
107
105
108
class(pyplot), intent (inout ) :: me ! ! pyplot handler
106
109
logical , intent (in ), optional :: grid ! ! activate grid drawing
@@ -120,6 +123,7 @@ subroutine initialize(me, grid, xlabel, ylabel, zlabel, title, legend, use_numpy
120
123
logical , intent (in ), optional :: mplot3d ! ! set true for 3d plots (cannot use with polar)
121
124
logical , intent (in ), optional :: axis_equal ! ! set true for axis = 'equal'
122
125
logical , intent (in ), optional :: polar ! ! set true for polar plots (cannot use with mplot3d)
126
+ character (len=* ), intent (in ), optional :: real_fmt ! ! format string for real numbers (examples: '(E30.16)' [default], '*')
123
127
124
128
character (len= max_int_len) :: width_str ! ! figure width dummy string
125
129
character (len= max_int_len) :: height_str ! ! figure height dummy string
@@ -129,6 +133,7 @@ subroutine initialize(me, grid, xlabel, ylabel, zlabel, title, legend, use_numpy
129
133
character (len= max_int_len) :: ytick_labelsize_str ! ! size of x axis tick labels dummy string
130
134
character (len= max_int_len) :: ztick_labelsize_str ! ! size of z axis tick labels dummy string
131
135
character (len= max_int_len) :: legend_fontsize_str ! ! size of legend font dummy string
136
+
132
137
character (len=* ), parameter :: default_font_size_str = ' 10' ! ! the default font size for plots
133
138
134
139
call me% destroy()
@@ -162,6 +167,11 @@ subroutine initialize(me, grid, xlabel, ylabel, zlabel, title, legend, use_numpy
162
167
else
163
168
me% axis_equal = .false.
164
169
end if
170
+ if (present (real_fmt)) then
171
+ me% real_fmt = trim (adjustl (real_fmt))
172
+ else
173
+ me% real_fmt = real_fmt_default
174
+ end if
165
175
166
176
call optional_int_to_string(font_size, font_size_str, default_font_size_str)
167
177
call optional_int_to_string(axes_labelsize, axes_labelsize_str, default_font_size_str)
@@ -249,12 +259,12 @@ subroutine add_plot(me, x, y, label, linestyle, markersize, linewidth, xlim, yli
249
259
if (allocated (me% str)) then
250
260
251
261
! axis limits (optional):
252
- if (present (xlim)) call vec_to_string(xlim, xlimstr, me% use_numpy)
253
- if (present (ylim)) call vec_to_string(ylim, ylimstr, me% use_numpy)
262
+ if (present (xlim)) call vec_to_string(xlim, me % real_fmt, xlimstr, me% use_numpy)
263
+ if (present (ylim)) call vec_to_string(ylim, me % real_fmt, ylimstr, me% use_numpy)
254
264
255
265
! convert the arrays to strings:
256
- call vec_to_string(x, xstr, me% use_numpy)
257
- call vec_to_string(y, ystr, me% use_numpy)
266
+ call vec_to_string(x, me % real_fmt, xstr, me% use_numpy)
267
+ call vec_to_string(y, me % real_fmt, ystr, me% use_numpy)
258
268
259
269
! get optional inputs (if not present, set default value):
260
270
call optional_int_to_string(markersize, imark, ' 3' )
@@ -298,7 +308,7 @@ end subroutine add_plot
298
308
!
299
309
! @note This requires `use_numpy` to be True.
300
310
301
- subroutine add_contour (me , x , y , z , label , linestyle , linewidth , levels , color )
311
+ subroutine add_contour (me , x , y , z , label , linestyle , linewidth , levels , color , filled , cmap )
302
312
303
313
class(pyplot), intent (inout ) :: me ! ! pyplot handler
304
314
real (wp),dimension (:), intent (in ) :: x ! ! x values
@@ -309,6 +319,8 @@ subroutine add_contour(me, x, y, z, label, linestyle, linewidth, levels, color)
309
319
integer , intent (in ), optional :: linewidth ! ! width of the plot line
310
320
real (wp),dimension (:), intent (in ), optional :: levels ! ! contour levels to plot
311
321
character (len=* ), intent (in ), optional :: color ! ! color of the contour line
322
+ logical , intent (in ), optional :: filled ! ! use filled control (default=False)
323
+ character (len=* ), intent (in ), optional :: cmap ! ! colormap if filled=True (examples: 'jet', 'bone')
312
324
313
325
character (len= :), allocatable :: xstr ! ! x values strinfied
314
326
character (len= :), allocatable :: ystr ! ! y values strinfied
@@ -322,14 +334,15 @@ subroutine add_contour(me, x, y, z, label, linestyle, linewidth, levels, color)
322
334
character (len=* ), parameter :: yname_ = ' Y' ! ! Y variable name for contour
323
335
character (len=* ), parameter :: zname_ = ' Z' ! ! Z variable name for contour
324
336
character (len= :), allocatable :: extras ! ! optional stuff
337
+ character (len= :), allocatable :: contourfunc ! ! 'contour' or 'contourf'
325
338
326
339
if (allocated (me% str)) then
327
340
328
341
! convert the arrays to strings:
329
- call vec_to_string(x, xstr, me% use_numpy)
330
- call vec_to_string(y, ystr, me% use_numpy)
331
- call matrix_to_string(z, zstr, me% use_numpy)
332
- if (present (levels)) call vec_to_string(levels, levelstr, me% use_numpy)
342
+ call vec_to_string(x, me % real_fmt, xstr, me% use_numpy)
343
+ call vec_to_string(y, me % real_fmt, ystr, me% use_numpy)
344
+ call matrix_to_string(z, me % real_fmt, zstr, me% use_numpy)
345
+ if (present (levels)) call vec_to_string(levels, me % real_fmt, levelstr, me% use_numpy)
333
346
334
347
! get optional inputs (if not present, set default value):
335
348
call optional_int_to_string(linewidth, iline, ' 3' )
@@ -349,9 +362,16 @@ subroutine add_contour(me, x, y, z, label, linestyle, linewidth, levels, color)
349
362
if (present (levels)) extras = extras// ' ,' // ' levels=' // levelstr
350
363
if (present (color)) extras = extras// ' ,' // ' colors="' // color// ' "'
351
364
if (present (linewidth)) extras = extras// ' ,' // ' linewidths=' // trim (adjustl (iline))
365
+ if (present (cmap)) extras = extras// ' ,' // ' cmap="' // cmap// ' "'
366
+
367
+ ! filled or regular:
368
+ contourfunc = ' contour' ! default
369
+ if (present (filled)) then
370
+ if (filled) contourfunc = ' contourf' ! filled contour
371
+ end if
352
372
353
373
! write the plot statement:
354
- call me% add_str(' CS = ax.contour (' // xname_// ' ,' // yname_// ' ,' // zname_// ' ,' // &
374
+ call me% add_str(' CS = ax.' // contourfunc // ' (' // xname_// ' ,' // yname_// ' ,' // zname_// ' ,' // &
355
375
' label="' // trim (label)// ' ",' // &
356
376
' linestyles="' // trim (adjustl (linestyle))// ' "' // &
357
377
extras// ' )' )
@@ -396,9 +416,9 @@ subroutine add_3d_plot(me, x, y, z, label, linestyle, markersize, linewidth)
396
416
if (allocated (me% str)) then
397
417
398
418
! convert the arrays to strings:
399
- call vec_to_string(x, xstr, me% use_numpy)
400
- call vec_to_string(y, ystr, me% use_numpy)
401
- call vec_to_string(z, zstr, me% use_numpy)
419
+ call vec_to_string(x, me % real_fmt, xstr, me% use_numpy)
420
+ call vec_to_string(y, me % real_fmt, ystr, me% use_numpy)
421
+ call vec_to_string(z, me % real_fmt, zstr, me% use_numpy)
402
422
403
423
! get optional inputs (if not present, set default value):
404
424
call optional_int_to_string(markersize, imark, ' 3' )
@@ -466,15 +486,15 @@ subroutine add_bar(me, left, height, label, width, bottom, color, yerr, align, x
466
486
if (allocated (me% str)) then
467
487
468
488
! axis limits (optional):
469
- if (present (xlim)) call vec_to_string(xlim, xlimstr, me% use_numpy)
470
- if (present (ylim)) call vec_to_string(ylim, ylimstr, me% use_numpy)
489
+ if (present (xlim)) call vec_to_string(xlim, me % real_fmt, xlimstr, me% use_numpy)
490
+ if (present (ylim)) call vec_to_string(ylim, me % real_fmt, ylimstr, me% use_numpy)
471
491
472
492
! convert the arrays to strings:
473
- call vec_to_string(left, xstr, me% use_numpy)
474
- call vec_to_string(height, ystr, me% use_numpy)
475
- if (present (width)) call vec_to_string(width, wstr, me% use_numpy)
476
- if (present (bottom)) call vec_to_string(bottom, bstr, me% use_numpy)
477
- if (present (yerr)) call vec_to_string(yerr, yerr_str, me% use_numpy)
493
+ call vec_to_string(left, me % real_fmt, xstr, me% use_numpy)
494
+ call vec_to_string(height, me % real_fmt, ystr, me% use_numpy)
495
+ if (present (width)) call vec_to_string(width, me % real_fmt, wstr, me% use_numpy)
496
+ if (present (bottom)) call vec_to_string(bottom, me % real_fmt, bstr, me% use_numpy)
497
+ if (present (yerr)) call vec_to_string(yerr, me % real_fmt, yerr_str, me% use_numpy)
478
498
479
499
! write the arrays:
480
500
call me% add_str(trim (xname)// ' = ' // xstr)
@@ -562,9 +582,10 @@ end subroutine integer_to_string
562
582
!
563
583
! Real vector to string.
564
584
565
- subroutine vec_to_string (v , str , use_numpy )
585
+ subroutine vec_to_string (v , fmt , str , use_numpy )
566
586
567
587
real (wp), dimension (:), intent (in ) :: v ! ! real values
588
+ character (len=* ), intent (in ) :: fmt ! ! real format string
568
589
character (len= :), allocatable , intent (out ) :: str ! ! real values stringified
569
590
logical , intent (in ) :: use_numpy ! ! activate numpy python module usage
570
591
@@ -574,7 +595,11 @@ subroutine vec_to_string(v, str, use_numpy)
574
595
575
596
str = ' ['
576
597
do i= 1 , size (v)
577
- write (tmp, real_fmt, iostat= istat) v(i)
598
+ if (fmt==' *' ) then
599
+ write (tmp, * , iostat= istat) v(i)
600
+ else
601
+ write (tmp, fmt, iostat= istat) v(i)
602
+ end if
578
603
if (istat/= 0 ) error stop ' Error in vec_to_string'
579
604
str = str// trim (adjustl (tmp))
580
605
if (i< size (v)) str = str // ' ,'
@@ -592,9 +617,10 @@ end subroutine vec_to_string
592
617
!
593
618
! Real matrix (rank 2) to string.
594
619
595
- subroutine matrix_to_string (v , str , use_numpy )
620
+ subroutine matrix_to_string (v , fmt , str , use_numpy )
596
621
597
622
real (wp), dimension (:,:), intent (in ) :: v ! ! real values
623
+ character (len=* ), intent (in ) :: fmt ! ! real format string
598
624
character (len= :), allocatable , intent (out ) :: str ! ! real values stringified
599
625
logical , intent (in ) :: use_numpy ! ! activate numpy python module usage
600
626
@@ -603,9 +629,9 @@ subroutine matrix_to_string(v, str, use_numpy)
603
629
604
630
str = ' ['
605
631
do i= 1 , size (v,1 ) ! rows
606
- call vec_to_string(v(i,:), tmp, use_numpy) ! one row at a time
632
+ call vec_to_string(v(i,:), fmt, tmp, use_numpy) ! one row at a time
607
633
str = str// trim (adjustl (tmp))
608
- if (i< size (v)) str = str // ' ,'
634
+ if (i< size (v, 1 )) str = str // ' ,'
609
635
end do
610
636
str = str // ' ]'
611
637
0 commit comments