Skip to content

Commit 89f4cd2

Browse files
Add jittering
1 parent 6de5bd5 commit 89f4cd2

5 files changed

Lines changed: 221 additions & 1 deletion

File tree

examples/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ target_link_libraries(margins_example fplot)
153153
add_executable(box_whisker_example box_whisker_example.f90)
154154
target_link_libraries(box_whisker_example fplot fstring::fstring)
155155

156+
# Example 39
157+
add_executable(jitter_plot_example jitter_plot_example.f90)
158+
target_link_libraries(jitter_plot_example fplot)
159+
156160
if (${BUILD_SHARED_LIBS} AND WIN32)
157161
add_custom_command(
158162
TARGET generic_2d_plot

examples/jitter_plot_example.f90

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
program example
2+
use iso_fortran_env
3+
use fplot_core
4+
implicit none
5+
6+
! Local Variables
7+
integer(int32), parameter :: n1 = 100
8+
integer(int32), parameter :: n2 = 100
9+
integer(int32), parameter :: n = n1 + n2
10+
real(real64) :: x(n), y(n)
11+
type(name_value_pair) :: labels(2)
12+
type(plot_2d) :: plt
13+
type(plot_data_2d) :: pd
14+
class(plot_axis), pointer :: xAxis
15+
16+
! Create the data sets
17+
call random_number(y)
18+
x(1:n1) = 1.0d0
19+
x(n1+1:n) = 2.0d0
20+
21+
! Define the labels
22+
labels(1)%name = "A"
23+
labels(1)%value = 1.0d0
24+
25+
labels(2)%name = "B"
26+
labels(2)%value = 2.0d0
27+
28+
! Create the plot
29+
call plt%initialize()
30+
call plt%set_show_gridlines(.false.)
31+
call plt%set_use_jittering(.true.)
32+
xAxis => plt%get_x_axis()
33+
34+
call xAxis%set_manual_tic_labels(labels)
35+
call xAxis%set_limits(0.5d0, 2.5d0)
36+
37+
call pd%define_data(x, y)
38+
call pd%set_draw_line(.false.)
39+
call pd%set_draw_markers(.true.)
40+
call pd%set_marker_scaling(1.5)
41+
call plt%push(pd)
42+
call plt%draw()
43+
end program

src/fplot_core.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ module fplot_core
150150
public :: y_axis
151151
public :: y2_axis
152152
public :: z_axis
153+
public :: name_value_pair
153154

154155
! FPLOT_TERMINAL.F90
155156
public :: terminal

src/fplot_plot_2d.f90

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ module fplot_plot_2d
2424
!! Display the secondary y axis?
2525
logical, private :: m_set2square = .false.
2626
!! Set to square scaling.
27+
logical, private :: m_useJitter = .false.
28+
!! Allow jittering?
29+
real(real32), private :: m_jitterOverlap = 1.0
30+
!! Jitter overlap.
31+
real(real32), private :: m_jitterSpread = 1.0
32+
!! Jitter horizontal spread.
2733
contains
2834
final :: p2d_clean_up
2935
procedure, public :: initialize => p2d_init
@@ -35,6 +41,12 @@ module fplot_plot_2d
3541
procedure, public :: set_use_y2_axis => p2d_set_use_y2
3642
procedure, public :: get_square_axes => p2d_get_square_axes
3743
procedure, public :: set_square_axes => p2d_set_square_axes
44+
procedure, public :: get_use_jittering => p2d_get_use_jitter
45+
procedure, public :: set_use_jittering => p2d_set_use_jitter
46+
procedure, public :: get_jitter_overlap => p2d_get_jitter_overlap
47+
procedure, public :: set_jitter_overlap => p2d_set_jitter_overlap
48+
procedure, public :: get_jitter_spread => p2d_get_jitter_spread
49+
procedure, public :: set_jitter_spread => p2d_set_jitter_spread
3850
end type
3951

4052
contains
@@ -273,6 +285,17 @@ function p2d_get_cmd(this) result(x)
273285
! call str%append(lbl%get_command_string())
274286
! end do
275287

288+
! Jittering
289+
call str%append(new_line('a'))
290+
if (this%get_use_jittering()) then
291+
call str%append("set jitter overlap ")
292+
call str%append(to_string(this%get_jitter_overlap()))
293+
call str%append(" spread ")
294+
call str%append(to_string(this%get_jitter_spread()))
295+
else
296+
call str%append("unset jitter")
297+
end if
298+
276299
! Define the plot function and data formatting commands
277300
n = this%get_count()
278301
call str%append(new_line('a'))
@@ -376,5 +399,65 @@ subroutine p2d_set_square_axes(this, x)
376399
this%m_set2square = x
377400
end subroutine
378401

402+
! ------------------------------------------------------------------------------
403+
pure function p2d_get_use_jitter(this) result(rst)
404+
!! Gets a logical value determining if jittering should be used.
405+
class(plot_2d), intent(in) :: this
406+
!! The plot_2d object.
407+
logical :: rst
408+
!! True if jittering should be used; else, false.
409+
rst = this%m_useJitter
410+
end function
411+
412+
! --------------------
413+
subroutine p2d_set_use_jitter(this, x)
414+
!! Sets a logical value determining if jittering should be used.
415+
class(plot_2d), intent(inout) :: this
416+
!! The plot_2d object.
417+
logical, intent(in) :: x
418+
!! Set to true if jittering should be used; else, false.
419+
this%m_useJitter = x
420+
end subroutine
421+
422+
! ------------------------------------------------------------------------------
423+
pure function p2d_get_jitter_overlap(this) result(rst)
424+
!! Gets the jitter overalp.
425+
class(plot_2d), intent(in) :: this
426+
!! The plot_2d object.
427+
real(real32) :: rst
428+
!! The jitter overlap.
429+
rst = this%m_jitterOverlap
430+
end function
431+
432+
! --------------------
433+
subroutine p2d_set_jitter_overlap(this, x)
434+
!! Sets the jitter overlap.
435+
class(plot_2d), intent(inout) :: this
436+
!! The plot_2d object.
437+
real(real32), intent(in) :: x
438+
!! The jitter overlap.
439+
this%m_jitterOverlap = x
440+
end subroutine
441+
442+
! ------------------------------------------------------------------------------
443+
pure function p2d_get_jitter_spread(this) result(rst)
444+
!! Gets the jitter horizontal spread.
445+
class(plot_2d), intent(in) :: this
446+
!! The plot_2d object.
447+
real(real32) :: rst
448+
!! The jitter horizontal spread.
449+
rst = this%m_jitterSpread
450+
end function
451+
452+
! --------------------
453+
subroutine p2d_set_jitter_spread(this, x)
454+
!! Sets the jitter horizontal spread.
455+
class(plot_2d), intent(inout) :: this
456+
!! The plot_2d object.
457+
real(real32), intent(in) :: x
458+
!! The jitter horizontal spread.
459+
this%m_jitterSpread = x
460+
end subroutine
461+
379462
! ------------------------------------------------------------------------------
380463
end module

src/fplot_plot_axis.f90

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ module fplot_plot_axis
1313
public :: y_axis
1414
public :: y2_axis
1515
public :: z_axis
16+
public :: name_value_pair
17+
18+
type name_value_pair
19+
!! Defines a name-value pair.
20+
character(len = :), allocatable :: name
21+
!! The name.
22+
real(real64) :: value
23+
!! The associated value.
24+
end type
1625

1726
type, abstract, extends(plot_object) :: plot_axis
1827
!! Defines a plot axis object.
@@ -66,6 +75,10 @@ module fplot_plot_axis
6675
!! The axis title x offset, in characters.
6776
integer(int32), private :: m_titleYOffset = 0
6877
!! The axis title y offset, in characters.
78+
logical, private :: m_useManualTicLabels = .false.
79+
!! Use manual (user-defined) tic labels?
80+
type(name_value_pair), private, allocatable, dimension(:) :: m_ticLabels
81+
!! A list of user-defined tic labels.
6982
contains
7083
procedure, public :: get_title => pa_get_title
7184
procedure, public :: set_title => pa_set_title
@@ -110,6 +123,12 @@ module fplot_plot_axis
110123
procedure, public :: set_title_x_offset => pa_set_title_x_offset
111124
procedure, public :: get_title_y_offset => pa_get_title_y_offset
112125
procedure, public :: set_title_y_offset => pa_set_title_y_offset
126+
procedure, public :: get_use_manual_tic_labels => &
127+
pa_get_use_manual_tic_labels
128+
procedure, public :: set_use_manual_tic_labels => &
129+
pa_set_use_manual_tic_labels
130+
procedure, public :: get_manual_tic_labels => pa_get_manual_tic_labels
131+
procedure, public :: set_manual_tic_labels => pa_set_manual_tic_labels
113132
end type
114133

115134
interface
@@ -241,7 +260,8 @@ pure function pa_get_axis_limits(this) result(x)
241260
! --------------------
242261
subroutine pa_set_axis_limits(this, lower, upper)
243262
!! Gets the axis display limits, assuming autoscaling is not
244-
!! active for this axis.
263+
!! active for this axis. This routine also calls [[set_autoscale]] and
264+
!! sets the property value to false.
245265
class(plot_axis), intent(inout) :: this
246266
!! The plot_axis object.
247267
real(real64), intent(in) :: lower
@@ -250,6 +270,7 @@ subroutine pa_set_axis_limits(this, lower, upper)
250270
!! The upper display limit.
251271
this%m_limits(1) = min(lower, upper)
252272
this%m_limits(2) = max(lower, upper)
273+
call this%set_autoscale(.false.)
253274
end subroutine
254275

255276
! ------------------------------------------------------------------------------
@@ -286,6 +307,8 @@ function pa_get_cmd_string(this) result(txt)
286307
real(real32) :: angle
287308
character(len = :), allocatable :: axis, fmt
288309
real(real64) :: lim(2)
310+
integer(int32) :: i
311+
type(name_value_pair), allocatable, dimension(:) :: ticLabels
289312

290313
! Process
291314
axis = this%get_id_string()
@@ -400,6 +423,22 @@ function pa_get_cmd_string(this) result(txt)
400423
call str%append(to_string(this%get_zero_axis_line_width()))
401424
end if
402425

426+
! Use manual labels
427+
ticLabels = this%get_manual_tic_labels()
428+
if (this%get_use_manual_tic_labels() .and. size(ticLabels) > 0) then
429+
call str%append(new_line('a'))
430+
call str%append("set ")
431+
call str%append(this%get_id_string() // "tics(")
432+
do i = 1, size(ticLabels)
433+
call str%append('"')
434+
call str%append(ticLabels(i)%name)
435+
call str%append('" ')
436+
call str%append(to_string(ticLabels(i)%value))
437+
if (i /= size(ticLabels)) call str%append(", ")
438+
end do
439+
call str%append(")")
440+
end if
441+
403442
! Output
404443
txt = char(str%to_string())
405444
end function
@@ -711,6 +750,56 @@ subroutine pa_set_title_y_offset(this, x)
711750
this%m_titleYOffset = x
712751
end subroutine
713752

753+
! ------------------------------------------------------------------------------
754+
pure function pa_get_use_manual_tic_labels(this) result(rst)
755+
!! Gets a value determining if manual tic labels should be used.
756+
class(plot_axis), intent(in) :: this
757+
!! The plot_axis object.
758+
logical :: rst
759+
!! True if manual tic labels should be used; else, false.
760+
rst = this%m_useManualTicLabels
761+
end function
762+
763+
! --------------------
764+
subroutine pa_set_use_manual_tic_labels(this, x)
765+
!! Sets a value determining if manual tic labels should be used.
766+
class(plot_axis), intent(inout) :: this
767+
!! The plot_axis object.
768+
logical, intent(in) :: x
769+
!! Set to true if manual tic labels should be used; else, false.
770+
this%m_useManualTicLabels = x
771+
end subroutine
772+
773+
! ------------------------------------------------------------------------------
774+
pure function pa_get_manual_tic_labels(this) result(rst)
775+
!! Gets a list of manual tic labels.
776+
class(plot_axis), intent(in) :: this
777+
!! The plot_axis object.
778+
type(name_value_pair), allocatable, dimension(:) :: rst
779+
!! A list of name-value pairs where the name defines the label
780+
!! shown with the corresponding axis value.
781+
if (allocated(this%m_ticLabels)) then
782+
rst = this%m_ticLabels
783+
else
784+
allocate(rst(0))
785+
end if
786+
end function
787+
788+
! --------------------
789+
subroutine pa_set_manual_tic_labels(this, x)
790+
!! Sets a list of manual tic labels. This routine also sets
791+
!! [[set_use_manual_tic_labels]] to true.
792+
class(plot_axis), intent(inout) :: this
793+
!! The plot_axis object.
794+
type(name_value_pair), intent(in), dimension(:) :: x
795+
!! The list of tic values with the name component representing the
796+
!! displayed label text and the value is the associated axis value.
797+
798+
if (allocated(this%m_ticLabels)) deallocate(this%m_ticLabels)
799+
allocate(this%m_ticLabels(size(x)), source = x)
800+
call this%set_use_manual_tic_labels(.true.)
801+
end subroutine
802+
714803
! ******************************************************************************
715804
! X_AXIS MEMBERS
716805
! ------------------------------------------------------------------------------

0 commit comments

Comments
 (0)