From 7c6674d9eeb1dead7417b8a9958afe80527c2e92 Mon Sep 17 00:00:00 2001 From: jchristopherson Date: Wed, 10 Jun 2026 12:22:01 -0500 Subject: [PATCH 01/10] Update example --- examples/custom_colormap_example.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom_colormap_example.f90 b/examples/custom_colormap_example.f90 index 566c0d7..3c92c2d 100644 --- a/examples/custom_colormap_example.f90 +++ b/examples/custom_colormap_example.f90 @@ -1,7 +1,7 @@ program example use fplot_core use iso_fortran_env - use forcolormap, only : colormaps_list + use forcolormap implicit none ! Parameters From 3fd066b17be60a98ed80e757301754dbbc3ee29b Mon Sep 17 00:00:00 2001 From: jchristopherson Date: Wed, 10 Jun 2026 12:25:04 -0500 Subject: [PATCH 02/10] Clean up --- src/fplot_plot_data_histogram.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fplot_plot_data_histogram.f90 b/src/fplot_plot_data_histogram.f90 index adea5bf..e943ae3 100644 --- a/src/fplot_plot_data_histogram.f90 +++ b/src/fplot_plot_data_histogram.f90 @@ -7,7 +7,6 @@ module fplot_plot_data_histogram use ferror use strings use fplot_colors - use fplot_errors implicit none private public :: plot_data_histogram From e332c11ca2a97b389036a1dc3b1221cd7e5dc8c0 Mon Sep 17 00:00:00 2001 From: jchristopherson Date: Wed, 10 Jun 2026 13:29:46 -0500 Subject: [PATCH 03/10] Add box and whisker type --- src/CMakeLists.txt | 1 + src/fplot_core.f90 | 4 + src/fplot_plot_data_box_whisker.f90 | 202 ++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 src/fplot_plot_data_box_whisker.f90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d12978d..7c7b712 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,7 @@ set(FPLOT_SOURCES ${dir}/fplot_plot_data_3d.f90 ${dir}/fplot_surface_plot_data.f90 ${dir}/fplot_stats_plots.f90 + ${dir}/fplot_plot_data_box_whisker.f90 ) set(FPLOT_SOURCES ${FPLOT_SOURCES} PARENT_SCOPE) diff --git a/src/fplot_core.f90 b/src/fplot_core.f90 index 42abae9..c5f6249 100644 --- a/src/fplot_core.f90 +++ b/src/fplot_core.f90 @@ -41,6 +41,7 @@ module fplot_core use fplot_plot_bar use fplot_plot_polar use fplot_stats_plots + use fplot_plot_data_box_whisker implicit none private @@ -249,4 +250,7 @@ module fplot_core ! FPLOT_STATS_PLOTS.F90 public :: correlation_plot + + ! FPLOT_PLOT_DATA_BOX_WHISKER.F90 + public :: plot_data_box_whisker end module diff --git a/src/fplot_plot_data_box_whisker.f90 b/src/fplot_plot_data_box_whisker.f90 new file mode 100644 index 0000000..193544c --- /dev/null +++ b/src/fplot_plot_data_box_whisker.f90 @@ -0,0 +1,202 @@ +module fplot_plot_data_box_whisker + use iso_fortran_env + use fplot_plot_data + use fplot_errors + use fplot_colors + use ferror + use strings + implicit none + private + public :: plot_data_box_whisker + + type, extends(plot_data_colored) :: plot_data_box_whisker + !! A container for box-whisker plot data. + type(string), private, allocatable, dimension(:) :: m_x + !! The x-coordinate data. + real(real64), private, allocatable, dimension(:) :: m_boxMin + !! The minimum y-values for each box. + real(real64), private, allocatable, dimension(:) :: m_boxMax + !! The maximum y-values for each box. + real(real64), private, allocatable, dimension(:) :: m_whiskerMin + !! The minimum y-values for each whisker. + real(real64), private, allocatable, dimension(:) :: m_whiskerMax + !! The maximum y-values for each whisker. + logical, private :: m_useY2 = .false. + !! Plot against the secondary y-axis? + contains + procedure, public :: define_data => pdbw_define_data_xstring + procedure, public :: get_command_string => pdbw_get_cmd + procedure, public :: get_data_string => pdbw_get_data_cmd + procedure, public :: get_draw_against_y2 => pdbw_get_use_y2 + procedure, public :: set_draw_against_y2 => pdbw_set_use_y2 + end type + +contains +! ------------------------------------------------------------------------------ +subroutine pdbw_define_data_xstring(this, x, boxmin, boxmax, whiskermin, & + whiskermax, err) + !! Defines the data set to plot. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + type(string), intent(in), dimension(:) :: x + !! The x-coordinate data. + real(real64), intent(in), dimension(size(x)) :: boxmin + !! The minimum y-values for each box. + real(real64), intent(in), dimension(size(x)) :: boxmax + !! The maximum y-values for each box. + real(real64), intent(in), dimension(size(x)) :: whiskermin + !! The minimum y-values for each whisker. + real(real64), intent(in), dimension(size(x)) :: whiskermax + !! The maximum y-values for each whisker. + class(errors), intent(inout), optional, target :: err + !! An error handling object. + + ! Local Variables + integer(int32) :: n, flag + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + n = size(x) + + ! Allocations + if (allocated(this%m_x)) deallocate(this%m_x) + if (allocated(this%m_boxMin)) deallocate(this%m_boxMin) + if (allocated(this%m_boxMax)) deallocate(this%m_boxMax) + if (allocated(this%m_whiskerMin)) deallocate(this%m_whiskerMin) + if (allocated(this%m_whiskerMax)) deallocate(this%m_whiskerMax) + + allocate(this%m_x(n), source = x, stat = flag) + if (flag == 0) allocate(this%m_boxMin(n), source = boxmin, stat = flag) + if (flag == 0) allocate(this%m_boxMax(n), source = boxmax, stat = flag) + if (flag == 0) allocate(this%m_whiskerMin(n), source = whiskermin, stat = flag) + if (flag == 0) allocate(this%m_whiskerMax(n), source = whiskermax, stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "pdbw_define_data_xstring", flag) + return + end if +end subroutine + +! ------------------------------------------------------------------------------ +function pdbw_get_cmd(this) result(rst) + !! Gets the GNUPLOT command string for this object. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + character(len = :), allocatable :: rst + !! The command string. + + ! Local Variables + type(string_builder) :: str + integer(int32) :: n, nname + type(color) :: clr + + ! Title + nname = len_trim(this%get_name()) + if (n > 0) then + call str%append(' "-" title "') + call str%append(this%get_name()) + call str%append('"') + else + call str%append(' "-" notitle') + end if + + ! Style + call str%append("using ($0+1):2:3:4:5:xtic(1) with candlesticks") + + ! Whisker bars + + ! Color + clr = this%get_line_color() + call str%append(' lc rgb "#') + call str%append(clr%to_hex_string()) + call str%append('"') +end function + +! ------------------------------------------------------------------------------ +function pdbw_get_data_cmd(this) result(rst) + !! Gets the GNUPLOT command string defining the data for this object. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + character(len = :), allocatable :: rst + !! The command string. + + ! Local Variables + type(string_builder) :: str + integer(int32) :: i, n + character :: delimiter, nl + + ! Initialization + delimiter = achar(9) + nl = new_line(nl) + n = size(this%m_x) + + ! Process + do i = 1, n + call str%append(this%m_x(i)) + call str%append(delimiter) + call str%append(to_string(this%m_boxMin(i))) + call str%append(delimiter) + call str%append(to_string(this%m_whiskerMin(i))) + call str%append(delimiter) + call str%append(to_string(this%m_whiskerMax(i))) + call str%append(delimiter) + call str%append(to_string(this%m_boxMax(i))) + call str%append(nl) + end do + + ! End + rst = char(str%to_string()) +end function + +! ------------------------------------------------------------------------------ +function pdbw_get_axes_cmd(this) result(rst) + !! Gets the GNUPLOT command string defining which axes the data is to be + !! plotted against. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + character(len = :), allocatable :: rst + !! The command string. + + ! Define which axes the data is to be plotted against + if (this%get_draw_against_y2()) then + rst = "axes x1y2" + else + rst = "axes x1y1" + end if +end function + +! ------------------------------------------------------------------------------ +pure function pdbw_get_use_y2(this) result(rst) + !! Gets a value determining if the data is to be plotted against the + !! secondary y axis. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + logical :: rst + !! Returns true if the data is to be plotted against the secondary y + !! axis; else, false for the primary y axis. + rst = this%m_useY2 +end function + +! -------------------- +subroutine pdbw_set_use_y2(this, x) + !! Sets a value determining if the data is to be plotted against the + !! secondary y axis. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + logical, intent(in) :: x + !! Set to true if the data is to be plotted against the secondary y + !! axis; else, false for the primary y axis. + this%m_useY2 = x +end subroutine + +! ------------------------------------------------------------------------------ + +! ------------------------------------------------------------------------------ + +! ------------------------------------------------------------------------------ +end module \ No newline at end of file From 9aeb9bf8d19327f1db2a1106d88ee49c8f341dc4 Mon Sep 17 00:00:00 2001 From: Jason Christopherson Date: Wed, 10 Jun 2026 16:52:27 -0500 Subject: [PATCH 04/10] Add example --- examples/CMakeLists.txt | 8 +++++++- examples/box_whisker_example.f90 | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 examples/box_whisker_example.f90 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4e184ab..d37b62a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,5 @@ +find_package(fstring QUIET) + # Example 1 add_executable(generic_2d_plot generic_2d_plot.f90) target_link_libraries(generic_2d_plot fplot) @@ -147,6 +149,10 @@ target_link_libraries(correlation_plot_example fplot) add_executable(margins_example margins_example.f90) target_link_libraries(margins_example fplot) +# Example 38 +add_executable(box_whisker_example box_whisker_example.f90) +target_link_libraries(box_whisker_example fplot fstring::fstring) + if (${BUILD_SHARED_LIBS} AND WIN32) add_custom_command( TARGET generic_2d_plot @@ -156,4 +162,4 @@ if (${BUILD_SHARED_LIBS} AND WIN32) $ COMMAND_EXPAND_LISTS ) -endif() \ No newline at end of file +endif() diff --git a/examples/box_whisker_example.f90 b/examples/box_whisker_example.f90 new file mode 100644 index 0000000..a2968fe --- /dev/null +++ b/examples/box_whisker_example.f90 @@ -0,0 +1,35 @@ +program example + use iso_fortran_env + use fplot_core + use strings + implicit none + + ! Variables + integer(int32), parameter :: n = 5 + integer(int32) :: i + type(string) :: titles(n) + real(real64) :: boxmin(n), boxmax(n), whiskermin(n), whiskermax(n) + type(plot_2d) :: plt + type(plot_data_box_whisker) :: pd + + ! Initialization + do i = 1, n + titles(i) = "Item " // to_string(i) + end do + call random_number(whiskermin) + call random_number(whiskermax) + call random_number(boxmin) + call random_number(boxmax) + + ! Ensure proper order + boxmin = boxmin + whiskermin + boxmax = boxmin + boxmax + whiskermax = whiskermax + boxmax + + ! Create the plot + call plt%initialize() + + call pd%define_data(titles, boxmin, boxmax, whiskermin, whiskermax) + call plt%push(pd) + call plt%draw() +end program \ No newline at end of file From 4fdacc65dd385e6953da027586f9d36ec563443f Mon Sep 17 00:00:00 2001 From: Jason Christopherson Date: Wed, 10 Jun 2026 16:52:31 -0500 Subject: [PATCH 05/10] Clean up --- src/fplot_plot_data_box_whisker.f90 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fplot_plot_data_box_whisker.f90 b/src/fplot_plot_data_box_whisker.f90 index 193544c..f8436e8 100644 --- a/src/fplot_plot_data_box_whisker.f90 +++ b/src/fplot_plot_data_box_whisker.f90 @@ -106,7 +106,7 @@ function pdbw_get_cmd(this) result(rst) end if ! Style - call str%append("using ($0+1):2:3:4:5:xtic(1) with candlesticks") + call str%append(" using ($0+1):2:3:4:5:xtic(1) with candlesticks") ! Whisker bars @@ -115,6 +115,9 @@ function pdbw_get_cmd(this) result(rst) call str%append(' lc rgb "#') call str%append(clr%to_hex_string()) call str%append('"') + + ! End + rst = char(str%to_string()) end function ! ------------------------------------------------------------------------------ From a0aeba867e3ed22a8d3acc5eb8b02108a8627178 Mon Sep 17 00:00:00 2001 From: Jason Christopherson Date: Thu, 11 Jun 2026 06:02:17 -0500 Subject: [PATCH 06/10] Add to box and whisker --- examples/box_whisker_example.f90 | 18 ++-- src/fplot_plot_data_box_whisker.f90 | 130 ++++++++++++++++++++++++++-- 2 files changed, 132 insertions(+), 16 deletions(-) diff --git a/examples/box_whisker_example.f90 b/examples/box_whisker_example.f90 index a2968fe..2a657c9 100644 --- a/examples/box_whisker_example.f90 +++ b/examples/box_whisker_example.f90 @@ -5,7 +5,7 @@ program example implicit none ! Variables - integer(int32), parameter :: n = 5 + integer(int32), parameter :: n = 3 integer(int32) :: i type(string) :: titles(n) real(real64) :: boxmin(n), boxmax(n), whiskermin(n), whiskermax(n) @@ -14,22 +14,18 @@ program example ! Initialization do i = 1, n - titles(i) = "Item " // to_string(i) + titles(i) = "Item-" // to_string(i) end do - call random_number(whiskermin) - call random_number(whiskermax) - call random_number(boxmin) - call random_number(boxmax) - - ! Ensure proper order - boxmin = boxmin + whiskermin - boxmax = boxmin + boxmax - whiskermax = whiskermax + boxmax + boxmin = [4.5d0, 5.0d0, 6.0d0] + boxmax = [7.5d0, 8.0d0, 9.0d0] + whiskermin = [3.0d0, 4.0d0, 5.0d0] + whiskermax = [9.0d0, 10.0d0, 11.0d0] ! Create the plot call plt%initialize() call pd%define_data(titles, boxmin, boxmax, whiskermin, whiskermax) + call pd%set_line_width(2.0) call plt%push(pd) call plt%draw() end program \ No newline at end of file diff --git a/src/fplot_plot_data_box_whisker.f90 b/src/fplot_plot_data_box_whisker.f90 index f8436e8..4838436 100644 --- a/src/fplot_plot_data_box_whisker.f90 +++ b/src/fplot_plot_data_box_whisker.f90 @@ -23,12 +23,28 @@ module fplot_plot_data_box_whisker !! The maximum y-values for each whisker. logical, private :: m_useY2 = .false. !! Plot against the secondary y-axis? + logical, private :: m_whiskerbars = .true. + !! Use horizontal whisker bar caps? + real(real32), private :: m_whiskerWidth = 1.0 + !! On a scale of 0 -> 1, the whiskerwidth. + real(real32), private :: m_lineWidth = 1.0 + !! The line width. + real(real32), private :: m_boxWidth = 0.05 + !! The box width. contains procedure, public :: define_data => pdbw_define_data_xstring procedure, public :: get_command_string => pdbw_get_cmd procedure, public :: get_data_string => pdbw_get_data_cmd procedure, public :: get_draw_against_y2 => pdbw_get_use_y2 procedure, public :: set_draw_against_y2 => pdbw_set_use_y2 + procedure, public :: get_use_whiskerbars => pdbw_get_use_whiskerbars + procedure, public :: set_use_whiskerbars => pdbw_set_use_whiskerbars + procedure, public :: get_whiskerbar_width => pdbw_get_whiskerbar_width + procedure, public :: set_whiskerbar_width => pdbw_set_whiskerbar_width + procedure, public :: get_line_width => pdbw_get_line_width + procedure, public :: set_line_width => pdbw_set_line_width + procedure, public :: get_box_width => pdbw_get_box_width + procedure, public :: set_box_width => pdbw_set_box_width end type contains @@ -95,20 +111,27 @@ function pdbw_get_cmd(this) result(rst) integer(int32) :: n, nname type(color) :: clr + ! Style + ! call str%append(' "-" using ($0+1):2:3:4:5:xtic(1) with candlesticks') + call str%append(' "-" using ($0+1):2:3:4:5:(') + call str%append(to_string(this%get_box_width())) + call str%append("):xtic(1) with candlesticks") + ! Title nname = len_trim(this%get_name()) if (n > 0) then - call str%append(' "-" title "') + call str%append(' title "') call str%append(this%get_name()) call str%append('"') else - call str%append(' "-" notitle') + call str%append(' notitle') end if - ! Style - call str%append(" using ($0+1):2:3:4:5:xtic(1) with candlesticks") - ! Whisker bars + if (this%get_use_whiskerbars()) then + call str%append(" whiskerbars ") + call str%append(to_string(this%get_whiskerbar_width())) + end if ! Color clr = this%get_line_color() @@ -116,6 +139,10 @@ function pdbw_get_cmd(this) result(rst) call str%append(clr%to_hex_string()) call str%append('"') + ! Line Width + call str%append(" lw ") + call str%append(to_string(this%get_line_width())) + ! End rst = char(str%to_string()) end function @@ -198,8 +225,101 @@ subroutine pdbw_set_use_y2(this, x) end subroutine ! ------------------------------------------------------------------------------ +pure function pdbw_get_use_whiskerbars(this) result(rst) + !! Gets a value determining if whiskerbars should be used. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + logical :: rst + !! True if whiskerbars should be used; else, false. + rst = this%m_whiskerbars +end function + +! -------------------- +subroutine pdbw_set_use_whiskerbars(this, x) + !! Sets a value determining if whiskerbars should be used. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + logical, intent(in) :: x + !! Set to true if whiskerbars should be used; else, false. + this%m_whiskerbars = x +end subroutine ! ------------------------------------------------------------------------------ +pure function pdbw_get_whiskerbar_width(this) result(rst) + !! Gets the width of whiskerbar. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + real(real32) :: rst + !! The width of the whiskerbar on a scale of 0:1 with 1 being the full + !! width. + rst = this%m_whiskerWidth +end function + +! -------------------- +subroutine pdbw_set_whiskerbar_width(this, x) + !! Sets the width of the whiskerbar. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + real(real32), intent(in) :: x + !! The width of the whiskerbar. This value is clamped to [0, 1] with + !! 1 representing full width. + + if (x < 0.0d0) then + this%m_whiskerWidth = 0.0d0 + else if (x > 1.0d0) then + this%m_whiskerWidth = 1.0d0 + else + this%m_whiskerWidth = x + end if +end subroutine + +! ------------------------------------------------------------------------------ +pure function pdbw_get_line_width(this) result(x) + !! Gets the width of the line, in pixels. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + real(real32) :: x + !! The line width. + x = this%m_lineWidth +end function + +! -------------------- +subroutine pdbw_set_line_width(this, x) + !! Sets the width of the line, in pixels. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + real(real32), intent(in) :: x + !! The line width. + this%m_lineWidth = x +end subroutine + +! ------------------------------------------------------------------------------ +pure function pdbw_get_box_width(this) result(rst) + !! Gets the box width. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + real(real32) :: rst + !! The box width. + rst = this%m_boxWidth +end function + +! -------------------- +subroutine pdbw_set_box_width(this, x) + !! Sets the box width. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + real(real32), intent(in) :: x + !! The box width. + this%m_boxWidth = x +end subroutine + +! ------------------------------------------------------------------------------ + +! -------------------- + +! ------------------------------------------------------------------------------ + +! -------------------- ! ------------------------------------------------------------------------------ end module \ No newline at end of file From c8b6fb4f78384cb25e261962d9c9a851e27b88cb Mon Sep 17 00:00:00 2001 From: Jason Christopherson Date: Thu, 11 Jun 2026 08:15:21 -0500 Subject: [PATCH 07/10] Add functionality --- src/fplot_plot_data_box_whisker.f90 | 53 +++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/fplot_plot_data_box_whisker.f90 b/src/fplot_plot_data_box_whisker.f90 index 4838436..a4ac262 100644 --- a/src/fplot_plot_data_box_whisker.f90 +++ b/src/fplot_plot_data_box_whisker.f90 @@ -31,6 +31,10 @@ module fplot_plot_data_box_whisker !! The line width. real(real32), private :: m_boxWidth = 0.05 !! The box width. + logical, private :: m_fillBoxes = .true. + !! Fill the boxes? + real(real32), private :: m_boxOpacity = 1.0 + !! Box opacity [0, 1.0]. contains procedure, public :: define_data => pdbw_define_data_xstring procedure, public :: get_command_string => pdbw_get_cmd @@ -45,6 +49,10 @@ module fplot_plot_data_box_whisker procedure, public :: set_line_width => pdbw_set_line_width procedure, public :: get_box_width => pdbw_get_box_width procedure, public :: set_box_width => pdbw_set_box_width + procedure, public :: get_fill_boxes => pdbw_get_fill_boxes + procedure, public :: set_fill_boxes => pdbw_set_fill_boxes + procedure, public :: get_box_fill_opacity => pdbw_get_opacity + procedure, public :: set_box_fill_opacity => pdbw_set_opacity end type contains @@ -143,6 +151,13 @@ function pdbw_get_cmd(this) result(rst) call str%append(" lw ") call str%append(to_string(this%get_line_width())) + ! Fill Boxes + if (this%get_fill_boxes()) then + call str%append(" fill solid ") + call str%append(to_string(this%get_box_fill_opacity())) + call str%append(" border") + end if + ! End rst = char(str%to_string()) end function @@ -295,7 +310,8 @@ subroutine pdbw_set_line_width(this, x) ! ------------------------------------------------------------------------------ pure function pdbw_get_box_width(this) result(rst) - !! Gets the box width. + !! Gets the box width. By default the x-axis is incremented in units of 1; + !! therefore, a box width of 1 will fully fill the space. class(plot_data_box_whisker), intent(in) :: this !! The plot_data_box_whisker object. real(real32) :: rst @@ -305,7 +321,8 @@ pure function pdbw_get_box_width(this) result(rst) ! -------------------- subroutine pdbw_set_box_width(this, x) - !! Sets the box width. + !! Sets the box width. By default the x-axis is incremented in units of 1; + !! therefore, a box width of 1 will fully fill the space. class(plot_data_box_whisker), intent(inout) :: this !! The plot_data_box_whisker object. real(real32), intent(in) :: x @@ -314,12 +331,44 @@ subroutine pdbw_set_box_width(this, x) end subroutine ! ------------------------------------------------------------------------------ +pure function pdbw_get_fill_boxes(this) result(rst) + !! Gets a value determining if the boxes should be filled. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + logical :: rst + !! True if the boxes are to be filled; else, false. + rst = this%m_fillBoxes +end function ! -------------------- +subroutine pdbw_set_fill_boxes(this, x) + !! Sets a value determining if the boxes should be filled. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + logical, intent(in) :: x + !! Set to true if the boxes are to be filled; else, false. + this%m_fillBoxes = x +end subroutine ! ------------------------------------------------------------------------------ +pure function pdbw_get_opacity(this) result(rst) + !! Gets the opacity of the box fill color. + class(plot_data_box_whisker), intent(in) :: this + !! The plot_data_box_whisker object. + real(real32) :: rst + !! The opacity on a scale from 0 to 1. + rst = this%m_boxOpacity +end function ! -------------------- +subroutine pdbw_set_opacity(this, x) + !! Sets the opacity of the box fill color. + class(plot_data_box_whisker), intent(inout) :: this + !! The plot_data_box_whisker object. + real(real32), intent(in) :: x + !! The opacity on a scale from 0 to 1. + this%m_boxOpacity = x +end subroutine ! ------------------------------------------------------------------------------ end module \ No newline at end of file From 1af4e69a768eaad26e03aa7e0179d08733d63dab Mon Sep 17 00:00:00 2001 From: jchristopherson Date: Thu, 11 Jun 2026 10:41:36 -0500 Subject: [PATCH 08/10] Add box and whisker functionality --- examples/box_whisker_example.f90 | 8 +++++++- src/CMakeLists.txt | 6 ++++++ src/fplot_plot_data_box_whisker.f90 | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/examples/box_whisker_example.f90 b/examples/box_whisker_example.f90 index 2a657c9..3bda5ab 100644 --- a/examples/box_whisker_example.f90 +++ b/examples/box_whisker_example.f90 @@ -11,10 +11,11 @@ program example real(real64) :: boxmin(n), boxmax(n), whiskermin(n), whiskermax(n) type(plot_2d) :: plt type(plot_data_box_whisker) :: pd + class(plot_axis), pointer :: xAxis ! Initialization do i = 1, n - titles(i) = "Item-" // to_string(i) + titles(i) = '"' // "Item " // to_string(i) // '"' end do boxmin = [4.5d0, 5.0d0, 6.0d0] boxmax = [7.5d0, 8.0d0, 9.0d0] @@ -23,9 +24,14 @@ program example ! Create the plot call plt%initialize() + xAxis => plt%get_x_axis() + call xAxis%set_autoscale(.false.) + call xAxis%set_limits(0.0d0, n + 1.0d0) call pd%define_data(titles, boxmin, boxmax, whiskermin, whiskermax) call pd%set_line_width(2.0) + call pd%set_box_fill_opacity(0.5) + call pd%set_box_width(0.1) call plt%push(pd) call plt%draw() end program \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c7b712..3d1846a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,7 @@ set(FPLOT_SOURCES ${FPLOT_SOURCES} PARENT_SCOPE) # Dependencies include(FetchContent) +find_package(OpenMP REQUIRED COMPONENTS Fortran) find_package(ferror QUIET) find_package(collections QUIET) find_package(geompack QUIET) @@ -134,6 +135,11 @@ target_link_libraries( $ ) +if (OpenMP_Fortran_FOUND) + target_link_libraries(${PROJECT_NAME} PRIVATE OpenMP::OpenMP_Fortran) + target_compile_definitions(${PROJECT_NAME} PRIVATE USEOPENMP=1) +endif() + set_target_properties( ${PROJECT_NAME} PROPERTIES diff --git a/src/fplot_plot_data_box_whisker.f90 b/src/fplot_plot_data_box_whisker.f90 index a4ac262..79c56b8 100644 --- a/src/fplot_plot_data_box_whisker.f90 +++ b/src/fplot_plot_data_box_whisker.f90 @@ -35,6 +35,8 @@ module fplot_plot_data_box_whisker !! Fill the boxes? real(real32), private :: m_boxOpacity = 1.0 !! Box opacity [0, 1.0]. + logical, private :: m_drawBorder = .true. + !! Draw the box border? contains procedure, public :: define_data => pdbw_define_data_xstring procedure, public :: get_command_string => pdbw_get_cmd From 62f9282e0765c332f35457cc31726da0093aa22d Mon Sep 17 00:00:00 2001 From: jchristopherson Date: Thu, 11 Jun 2026 10:43:23 -0500 Subject: [PATCH 09/10] Update documentation --- doc/index.html | 4 +- doc/interface/cm_get_string_result.html | 4 +- doc/interface/get_string_result.html | 8 +- doc/interface/operator(==).html | 4 +- doc/interface/operator(SLASH=).html | 4 +- doc/interface/pa_get_string_result.html | 4 +- doc/interface/pd_get_string_result.html | 4 +- doc/interface/simplify_polyline.html | 4 +- doc/interface/spd_get_int_value.html | 4 +- doc/interface/spd_get_string_result.html | 4 +- doc/interface/spd_get_value.html | 4 +- doc/interface/spd_set_value.html | 4 +- doc/interface/term_get_string_result.html | 8 +- doc/lists/files.html | 5 +- doc/lists/modules.html | 41 +- doc/lists/procedures.html | 4 +- doc/lists/types.html | 5 +- doc/module/fplot_arrow.html | 10 +- doc/module/fplot_colormap.html | 14 +- doc/module/fplot_colors.html | 6 +- doc/module/fplot_constants.html | 6 +- doc/module/fplot_core.html | 47 +- doc/module/fplot_core_routines.html | 4 +- doc/module/fplot_delaunay_tri_surface.html | 8 +- doc/module/fplot_errors.html | 4 +- doc/module/fplot_filled_plot_data.html | 8 +- doc/module/fplot_label.html | 6 +- doc/module/fplot_latex_terminal.html | 10 +- doc/module/fplot_legend.html | 8 +- doc/module/fplot_multiplot.html | 18 +- doc/module/fplot_plot.html | 26 +- doc/module/fplot_plot_2d.html | 12 +- doc/module/fplot_plot_3d.html | 14 +- doc/module/fplot_plot_axis.html | 8 +- doc/module/fplot_plot_bar.html | 4 +- doc/module/fplot_plot_data.html | 14 +- doc/module/fplot_plot_data_2d.html | 10 +- doc/module/fplot_plot_data_3d.html | 10 +- doc/module/fplot_plot_data_bar.html | 12 +- doc/module/fplot_plot_data_box_whisker.html | 540 ++++++ doc/module/fplot_plot_data_error_bars.html | 14 +- doc/module/fplot_plot_data_histogram.html | 20 +- doc/module/fplot_plot_data_tri_2d.html | 22 +- doc/module/fplot_plot_object.html | 4 +- doc/module/fplot_plot_polar.html | 18 +- doc/module/fplot_png_terminal.html | 12 +- doc/module/fplot_qt_terminal.html | 8 +- doc/module/fplot_simplify.html | 8 +- doc/module/fplot_stats_plots.html | 24 +- doc/module/fplot_surface_plot.html | 10 +- doc/module/fplot_surface_plot_data.html | 14 +- doc/module/fplot_terminal.html | 10 +- doc/module/fplot_tri_surface_plot_data.html | 14 +- .../fplot_triangulations_delaunay_2d.html | 10 +- doc/module/fplot_vector_field_plot_data.html | 16 +- doc/module/fplot_windows_terminal.html | 8 +- doc/module/fplot_wxt_terminal.html | 8 +- doc/proc/linspace.html | 4 +- doc/proc/logspace.html | 4 +- doc/proc/meshgrid.html | 4 +- .../report_array_size_mismatch_error.html | 4 +- doc/proc/report_file_create_error.html | 4 +- .../report_matrix_size_mismatch_error.html | 4 +- doc/proc/report_memory_error.html | 4 +- doc/search.html | 4 +- doc/sourcefile/fplot_arrow.f90.html | 6 +- doc/sourcefile/fplot_colormap.f90.html | 6 +- doc/sourcefile/fplot_colors.f90.html | 6 +- doc/sourcefile/fplot_constants.f90.html | 6 +- doc/sourcefile/fplot_core.f90.html | 428 ++--- doc/sourcefile/fplot_core_routines.f90.html | 4 +- .../fplot_delaunay_tri_surface.f90.html | 4 +- doc/sourcefile/fplot_errors.f90.html | 4 +- .../fplot_filled_plot_data.f90.html | 4 +- doc/sourcefile/fplot_label.f90.html | 4 +- doc/sourcefile/fplot_latex_terminal.f90.html | 6 +- doc/sourcefile/fplot_legend.f90.html | 6 +- doc/sourcefile/fplot_multiplot.f90.html | 6 +- doc/sourcefile/fplot_plot.f90.html | 6 +- doc/sourcefile/fplot_plot_2d.f90.html | 6 +- doc/sourcefile/fplot_plot_3d.f90.html | 6 +- doc/sourcefile/fplot_plot_axis.f90.html | 6 +- doc/sourcefile/fplot_plot_bar.f90.html | 4 +- doc/sourcefile/fplot_plot_data.f90.html | 6 +- doc/sourcefile/fplot_plot_data_2d.f90.html | 6 +- doc/sourcefile/fplot_plot_data_3d.f90.html | 6 +- doc/sourcefile/fplot_plot_data_bar.f90.html | 6 +- .../fplot_plot_data_box_whisker.f90.html | 644 +++++++ .../fplot_plot_data_error_bars.f90.html | 6 +- .../fplot_plot_data_histogram.f90.html | 601 +++--- .../fplot_plot_data_tri_2d.f90.html | 4 +- doc/sourcefile/fplot_plot_object.f90.html | 4 +- doc/sourcefile/fplot_plot_polar.f90.html | 6 +- doc/sourcefile/fplot_png_terminal.f90.html | 6 +- doc/sourcefile/fplot_qt_terminal.f90.html | 4 +- doc/sourcefile/fplot_simplify.f90.html | 6 +- doc/sourcefile/fplot_stats_plots.f90.html | 6 +- doc/sourcefile/fplot_surface_plot.f90.html | 4 +- .../fplot_surface_plot_data.f90.html | 6 +- doc/sourcefile/fplot_terminal.f90.html | 6 +- .../fplot_tri_surface_plot_data.f90.html | 4 +- .../fplot_triangulations_delaunay_2d.f90.html | 4 +- .../fplot_vector_field_plot_data.f90.html | 6 +- .../fplot_windows_terminal.f90.html | 4 +- doc/sourcefile/fplot_wxt_terminal.f90.html | 4 +- doc/src/fplot_core.f90 | 4 + doc/src/fplot_plot_data_box_whisker.f90 | 376 ++++ doc/src/fplot_plot_data_histogram.f90 | 3 +- doc/tipuesearch/tipuesearch_content.js | 2 +- doc/type/color.html | 4 +- doc/type/colormap.html | 6 +- doc/type/cool_colormap.html | 4 +- doc/type/correlation_plot.html | 12 +- doc/type/custom_colormap.html | 4 +- doc/type/delaunay_tri_2d.html | 6 +- doc/type/delaunay_tri_surface.html | 4 +- doc/type/earth_colormap.html | 4 +- doc/type/filled_plot_data.html | 6 +- doc/type/grey_colormap.html | 4 +- doc/type/hot_colormap.html | 4 +- doc/type/latex_terminal.html | 4 +- doc/type/legend.html | 6 +- doc/type/multiplot.html | 6 +- doc/type/parula_colormap.html | 6 +- doc/type/plot.html | 6 +- doc/type/plot_2d.html | 6 +- doc/type/plot_3d.html | 6 +- doc/type/plot_arrow.html | 6 +- doc/type/plot_axis.html | 6 +- doc/type/plot_bar.html | 6 +- doc/type/plot_data.html | 4 +- doc/type/plot_data_2d.html | 6 +- doc/type/plot_data_3d.html | 6 +- doc/type/plot_data_bar.html | 6 +- doc/type/plot_data_box_whisker.html | 1628 +++++++++++++++++ doc/type/plot_data_colored.html | 6 +- doc/type/plot_data_error_bars.html | 18 +- doc/type/plot_data_histogram.html | 36 +- doc/type/plot_data_tri_2d.html | 36 +- doc/type/plot_label.html | 4 +- doc/type/plot_object.html | 4 +- doc/type/plot_polar.html | 12 +- doc/type/png_terminal.html | 10 +- doc/type/qt_terminal.html | 10 +- doc/type/rainbow_colormap.html | 4 +- doc/type/scatter_plot_data.html | 6 +- doc/type/surface_plot.html | 12 +- doc/type/surface_plot_data.html | 24 +- doc/type/terminal.html | 12 +- doc/type/tri_surface_plot_data.html | 24 +- doc/type/vector_field_plot_data.html | 24 +- doc/type/windows_terminal.html | 10 +- doc/type/wxt_terminal.html | 10 +- doc/type/x_axis.html | 6 +- doc/type/y2_axis.html | 6 +- doc/type/y_axis.html | 6 +- doc/type/z_axis.html | 6 +- 157 files changed, 4334 insertions(+), 1136 deletions(-) create mode 100644 doc/module/fplot_plot_data_box_whisker.html create mode 100644 doc/sourcefile/fplot_plot_data_box_whisker.f90.html create mode 100644 doc/src/fplot_plot_data_box_whisker.f90 create mode 100644 doc/type/plot_data_box_whisker.html diff --git a/doc/index.html b/doc/index.html index 32ba9ff..1e40ea1 100644 --- a/doc/index.html +++ b/doc/index.html @@ -157,14 +157,14 @@

Derived Types