forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

%PL - some issues/questions
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6325
Location: Salford, UK

PostPosted: Mon May 18, 2020 12:37 pm    Post subject: Reply with quote

Martin

In my opinion it is not reasonable to judge ClearWin+ on the basis of your experience with %pl. %pl is a very small part of a very large library and your application of %pl is way above its designed purpose.
Back to top
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 67

PostPosted: Tue May 19, 2020 12:14 pm    Post subject: Reply with quote

Ken,

your code (with coordinates next to cursor) works PERFECT - thanks!
It means - the cursor shows the X,Y geodetical coordinates as defined previously in the graph (so it shows in the volatile small rectangular area something like this -1485265, -495564 and the X, Y coordinates are changing as cursor moves. Again, PERFECT!)

But I wanted to learn and achieve a little bit another thing. I will try to explain it here once again:

I read in a data from a file (87000+ points) which looks like this:

-1335000 -492000 -0.96 -0.84
-1335000 -491000 -0.97 -0.83
-1335000 -490000 -0.97 -0.82
-1335000 -489000 -0.98 -0.81
.....
.....

My goal is to show at the cursor (when I point with the cursor over a point
in the graph) its DX, DY values . It means (for example, when I point with cursor to the first point in the list above), I wanted to see preferably its DX, DY variations: -0.96, -0.84.
It could also be connected with X,Y, so the cursor would show
-1335000 -492000 -0.96 -0.84. But in any case, the DX,DY variations are very important, therefore I need them to see at the cursor position when hovering over a concrete point in the graph.

And here - I have no idea how to achieve it.

Thanks in advance for your comments.
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 268
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Tue May 19, 2020 1:55 pm    Post subject: Reply with quote

Martin,

I wrote the following before your last post:

I my example code shows you how to convert pixel coordinates to real world coordinates. With the real world coordinates, a search for the nearest actual grip point would be possible and I had wrongly assumed that you had a methodology to achieve this.

A brute force approach i.e. scanning all your data points would be intensive. However, at the zoom level where picking a grid point is feasible, it may be possible to scan all the grid data once, to produce a reduced set of grid points that are in the ‘current’ window, i.e. do this immediately after a zoom action. Then when you move the mouse about in a zoomed in widow you have a much smaller data set to operate on. This may become practical depending on what data structures that exist prior to the call to %pl. You might have to some duplicate information.


Consider this, as your grid coordinates appear to be equally spaced in the X and Y directions, consider using real arrays XX(1:N) with x grid coordinates and YY(1:M) with y grid coordinates.

This would allow a quicker nearest neighbour scan of just XX and YY and the location values from theses scans point to the physical location in an integer (1:N,1:M) array. The NR routines LOCATE and HUNT (probably better for this application) come to mind.

Your (1:N,1:M) integer array, would contain the index values to another set of arrays which contain the other data (whatever they are) associated with your storage grid points. All of this is separate and in addition to the data you pass to the plotting routine.
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6325
Location: Salford, UK

PostPosted: Tue May 19, 2020 1:57 pm    Post subject: Reply with quote

Code:
MODULE plData
  USE clrwin
  INTEGER(7) hwnd
CONTAINS
  INTEGER FUNCTION cb()
  CHARACTER(80) status,reason
  DOUBLE PRECISION x,y
  reason = clearwin_string@("CALLBACK_REASON")
  IF(reason == "MOUSE_MOVE")THEN
    ix = clearwin_info@("GRAPHICS_MOUSE_X")
    iy = clearwin_info@("GRAPHICS_MOUSE_Y")
    i = get_plot_data@(ix,iy,x,y)
    status = " "
    IF(x >= 0d0 .AND. y >= 0d0 .AND. x <= 1d0 .AND. y <= 1d0)THEN
      write(status,"(a,i3,a,i3,a)") ' Point(',ix,',',iy,')'
      CALL set_status_text@(hwnd,0,status)
      write(status,"(a,f6.2,a,f6.2,a)") ' Value(',x,',',y,')'
    ELSE
      CALL set_status_text@(hwnd,0,status)
    ENDIF         
    CALL set_status_text@(hwnd,1,status)
  ENDIF 
  cb = 2
  END FUNCTION
END MODULE plData
!-----------------------------------------------------------------------------------------------
PROGRAM main
  USE plData
  INTEGER,PARAMETER:: N=11,M=2
  DOUBLE PRECISION x(N),y(N)
  INTEGER i,sbparts(M)
  DATA sbparts /26,-1/
  DO i=1,N
    x(i)=0.1d0*(i-1)
    y(i)=x(i)*x(i)
  ENDDO
  i = winio@('%ww%ca[ClearWin+]&')
  i = winio@('%bg[BTNFACE]&')
  CALL winop@("%pl[title=Quadratic]")
  CALL winop@("%pl[width=2]")     
  CALL winop@("%pl[x_array]")     
  CALL winop@("%pl[link=curves]")
  CALL winop@("%pl[symbol=9]")   
  CALL winop@("%pl[colour=red]") 
  CALL winop@("%pl[pen_style=2]")
  CALL winop@("%pl[frame,gridlines]")
  CALL winop@("%pl[y_sigfigs=2]")
  CALL winop@("%pl[y_axis=y-data]")
  CALL winop@("%pl[x_max=1.0]")
  CALL winop@("%pl[y_max=1.0]")
  CALL winop@("%pl[dx=0.2]")
  CALL winop@("%pl[dy=0.2]")
  CALL winop@("%pl[full_mouse_input]")
  i=winio@('%`bg[white]&')
  i=winio@('%`*sb%lc&', M, sbparts, hwnd)
  i=winio@('%`bg&',RGB@(252,252,252))
  i=winio@('%pv%^pl',400,250,N,x,y,cb)
END PROGRAM

Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 268
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Tue May 19, 2020 4:06 pm    Post subject: Reply with quote

This demonstrates the concept I tried to explain above, obviously, the call to locate_dp and the logical function that test the returned value should be packaged into a single routine.

Code:
module from_kss_lib
implicit none
contains
!--------------------------------------------------------------------------------------------------
! #063  subroutine locate (xx, n, x, j)
!       Given an array xx(1:n), and given a value x, returns a value j such that x is between
!       xx(j) and xx(j+1). xx(1:n) must be monotonic, either increasing or decreasing. j=0 or
!       j=n is returned to indicate that x is out of range.
!--------------------------------------------------------------------------------------------------
    subroutine locate_dp(xx, n, x, j)
    implicit none
    integer, parameter :: dp = kind(1.d0)
    integer,                         intent(out) :: j
    integer,                         intent(in)  :: n
    real(kind = dp),                 intent(in)  :: x
    real(kind = dp), dimension(1:n), intent(in)  :: xx
    real, parameter :: zero_dp = 0.0d0
    integer          jl, jm, ju
      jl = 0 ; ju = n + 1
      do while (ju-jl .gt. 1)
        jm = (ju + jl)/2
        if ((xx(n) .ge. xx(1)) .eqv. (x .ge. xx(jm))) then
          jl = jm
        else
          ju = jm
        endif
      end do
      if      ((abs(x - xx(1)) .gt. zero_dp) .eqv. .false.) then
        j = 1
      else if ((abs(x - xx(n)) .gt. zero_dp) .eqv. .false.) then
        j = n-1
      else
        j = jl
      endif
    end subroutine locate_dp
   
end module from_kss_lib

    program main
    use from_kss_lib
    implicit none
    real*8 xx(1:10), xtest
    integer i,j
    do i = 1, 10, 1
      xx(i) = dble(i)
    end do
    do i = 1,20, 1
     
      xtest = 10.d0*random@()
     
      call locate_dp(xx, 10, xtest, j)
      if (j .eq. 0) then
        print*, xtest, ' outside range'
      else if (j .eq. 10) then
        print*, xtest, ' outside range'
      else if ( (xtest - xx(j) ) .lt. (xx(j+1) - xtest) ) then
        print*, xtest, ' nearest grid:', j, ' at ', xx(j)
      else if ( (xtest - xx(j)) .gt. (xx(j+1) - xtest) ) then
        print*, xtest, ' nearest grid:', j+1, ' at ', xx(j+1)
      else
        print*, xtest, ' at midpoint'
      end if
     
    end do
    end program main
[/quote]
Back to top
View user's profile Send private message Visit poster's website
DanRRight



Joined: 10 Mar 2008
Posts: 2187
Location: South Pole, Antarctica

PostPosted: Tue May 19, 2020 4:15 pm    Post subject: Reply with quote

Paul,
With your last example if modify x_max, y_max arbitrary way (not coinciding with the plotting data which ends at 1 in your example) how to get pixel (ix, iy) coordinated of each axis?

Things are it is often necessary to place something on axis or exactly nearby but the plotting program modifies user defined x_max and y_max (as well as x_min, y_min) to nearest nice looking for human eye numbers. As a result if i set x_max=1.29 the axis will be at 1.4 but if change dx it will be every time at different nice looking point. We never know which xy point this will be

Here is your example modified to show what i mean. Is there a way for example to place small rectangle DRAW_RECTANGLE@(ixx,iyy,ixxx,iyyy, icolor) exactly on both X an Y axis right top corner ?

Another question - i guess how in my example below the x axis title and numbering appears below the bottom x axis (like it should be in most of cases )? In my own other programs it appear in the middle x axis overwritten by the plotting points and i can not guess what causes this Smile ?

Note also that axis titles now are not perfectly centered in the middle of each axis but in the middle of only positive part of axis

Code:
MODULE plData
  USE clrwin
  INTEGER(7) hwnd
CONTAINS
  INTEGER FUNCTION cb()
  CHARACTER(80) status,reason
  DOUBLE PRECISION x,y
  reason = clearwin_string@("CALLBACK_REASON")
  IF(reason == "MOUSE_MOVE")THEN
    ix = clearwin_info@("GRAPHICS_MOUSE_X")
    iy = clearwin_info@("GRAPHICS_MOUSE_Y")
    i = get_plot_data@(ix,iy,x,y)
    status = " "
    IF(x >= 0d0 .AND. y >= 0d0 .AND. x <= 1d0 .AND. y <= 1d0)THEN
      write(status,"(a,i3,a,i3,a)") ' Point(',ix,',',iy,')'
      CALL set_status_text@(hwnd,0,status)
      write(status,"(a,f6.2,a,f6.2,a)") ' Value(',x,',',y,')'
    ELSE
      CALL set_status_text@(hwnd,0,status)
    ENDIF         
    CALL set_status_text@(hwnd,1,status)
  ENDIF
  cb = 2
  END FUNCTION
END MODULE plData
!---------------------------------------------------------------------------------------
PROGRAM main
  USE plData
  INTEGER,PARAMETER:: N=11,M=2
  DOUBLE PRECISION x(N),y(N)
  INTEGER i,sbparts(M)
  DATA sbparts /26,-1/
  DO i=1,N
    x(i)=0.1d0*(i-1)
    y(i)=x(i)*x(i)
  ENDDO
  i = winio@('%ww%ca[ClearWin+]&')
  i = winio@('%bg[BTNFACE]&')
  CALL winop@("%pl[title=Quadratic]")
  CALL winop@("%pl[width=2]")     
  CALL winop@("%pl[x_array]")     
  CALL winop@("%pl[link=curves]")
  CALL winop@("%pl[symbol=9]")   
  CALL winop@("%pl[colour=red]")
  CALL winop@("%pl[pen_style=2]")
  CALL winop@("%pl[frame,gridlines]")
  CALL winop@("%pl[y_sigfigs=2]")
  CALL winop@("%pl[x_axis=X-data]")
  CALL winop@("%pl[y_axis=Y-data]")
  CALL winop@("%pl[x_min=-0.66]")
  CALL winop@("%pl[x_max=1.36]")
  CALL winop@("%pl[y_min=-0.77]")
  CALL winop@("%pl[y_max=1.37]")
  CALL winop@("%pl[dx=0.2]")
  CALL winop@("%pl[dy=0.2]")
  CALL winop@("%pl[full_mouse_input]")
  i=winio@('%`bg[white]&')
  i=winio@('%`*sb%lc&', M, sbparts, hwnd)
  i=winio@('%`bg&',RGB@(252,252,252))
  i=winio@('%pv%^pl',600,400,N,x,y,cb)
END PROGRAM


Last edited by DanRRight on Tue May 19, 2020 4:49 pm; edited 1 time in total
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 67

PostPosted: Tue May 19, 2020 4:46 pm    Post subject: Reply with quote

Ken,

thanks for your tips!

I still have some formal questions to your last two responses, since i did not found it on the on-line help:

Q1:

Code:

i = COPY_GRAPHICS_REGION@(handle_internal_gr, 1, 1, gw, gh, handle_pl, 1, 1, gw, gh, 13369376 )


What is the real meaning of the numeric arguments 1,1 ... 1,1 ... 13369376 in the code above?

Q2:
In your last reply you used the NR abbreviation. I suppose it stands for NUMERICAL RECIPES. When I am right, are these NR somewhere on the web available for download free of charge or all NR are a payed option?

Thanks for your answers in advance!
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6325
Location: Salford, UK

PostPosted: Tue May 19, 2020 5:18 pm    Post subject: Reply with quote

Dan

Sometimes using a larger font causes the captions to be overwritten by the tick values. In which case there is an offset mechanism to adjust the position of a caption.

ir = GET_PLOT_POINT@(0.0d0, 0.0d0, xpix,ypix)

gives the pixel coordinates of the origin as double precision values.
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6325
Location: Salford, UK

PostPosted: Tue May 19, 2020 5:25 pm    Post subject: Reply with quote

Martin

Ken will be able to answer Q2.

For Q1, ff you are using Plato then type the name of the routine, place the caret at any point in the name and press F1.

Otherwise open FTN95.chm, and use the search facility.
Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 268
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Tue May 19, 2020 5:50 pm    Post subject: Reply with quote

Q1

https://www.silverfrost.com/ftn95-help/clearwinp/library/copy_graphics_region_.aspx

Q2
http://numerical.recipes/com/storefront.html

Some snippets of NR code can be found using a search engine.

There may be some alternatives to NR and perhaps I am guilty of thinking about programming using the FTN77 techniques I was taught in 1984 rather than ftn95 in 2020. (Not true since I no longer use common blocks!)

The code below does more or less the same job as that I previously posted.

Code:
    program main
    implicit none
    real*8 xx(1:10), xtest
    integer i,j
    do i = 1, 10, 1
      xx(i) = dble(i)
    end do
    do i = 1,20, 1
     
      xtest = 10.d0*random@()
     
      j = minloc(abs(xx - xtest), 1)
      print*, xtest, j
           
    end do
    end program main
Back to top
View user's profile Send private message Visit poster's website
DanRRight



Joined: 10 Mar 2008
Posts: 2187
Location: South Pole, Antarctica

PostPosted: Tue May 19, 2020 11:45 pm    Post subject: Re: Reply with quote

PaulLaidler wrote:
Dan

Sometimes using a larger font causes the captions to be overwritten by the tick values. In which case there is an offset mechanism to adjust the position of a caption.

ir = GET_PLOT_POINT@(0.0d0, 0.0d0, xpix,ypix)

gives the pixel coordinates of the origin as double precision values.


1) No, i asked about different thing. In your example the axis origin coincides with the data origin just by chance, in general case the numbering mechanism changes it at will. Here is how plot from your example above looks where i just moved position of axis. How to find the exact (ix, iy) or (x,y) positions of axis corners (marked in magenta)? Without knowing that user can not add anything to the plot using Clearwin graphics library like draw_line@, draw_characters, draw_ellipse@ etc

2) You can see the axis text is not centered and is too close to numbers despite your font has minimal size and is just 1 pixel thick. (BTW, on the 4k monitor i just do not see anything - this is how small the plot is and specifically how small numbers are and i plan to switch to 8k !!!)



3) How to make X axis numbering and X axis name not to be overwritten by the data? In your example numbering placed in the bottom axis, in my case in the middle - which is definitely wrong way to do - and i do not understand why and how to change that

Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6325
Location: Salford, UK

PostPosted: Wed May 20, 2020 8:22 am    Post subject: Reply with quote

Dan

1) I am not sure about the easiest and best way to do this. Maybe I should provide a routine that gives you the data values for the grid corners and maybe other things that users need.

2) I don't have an answer to this issue except to say that, at the moment as a user, you can either adjust the position of the caption or tell ClearWin+ not to draw them and then draw them directly in a startup callback. Here are some details from the help file..

Quote:
1. If ClearWin+ draws a title or axis caption at an inappropriate point then its position can be adjusted. For example [title=My Graph@(4.8)] using a decimal point, draws "My Graph" at a point that is adjusted 4 pixels to the right and 8 pixels down from its default position.

2. If an axis caption is not supplied then the defaults are lower case "x" and "y". Setting [x-axis=@] or [y-axis=@] prevents ClearWin+ from drawing the caption which could then be drawn using a callback function.

Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 268
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Wed May 20, 2020 11:39 am    Post subject: Reply with quote

Dan,

Try %pl[frame]. This was one of the first additions Paul made to the new %pl.

You can define the position of the frame using the margin option. If you don't specify the margins then it's more challenging. That's where the possible new routine Paul has suggested comes in.

Ken
Back to top
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 268
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Wed May 20, 2020 12:39 pm    Post subject: Reply with quote

Dan,

Example for you.

Code:
module example
use clrwin
implicit none
integer, parameter :: dp = kind(1.d0)
real(kind=dp) :: x_data(1:20), y_data(1:20)
integer :: gw = 800, gh=600
contains
 
integer function generate_data()
  integer i
  do i = 1, 20
    x_data(i) = random@()
    y_data(i) = random@()
  end do
  x_data = x_data - 0.5d0
  y_data = y_data - 0.5d0
  generate_data = 2
end function generate_data

integer function plot()
integer, save :: iw
  call winop@('%pl[independent,x_array,link=none,symbol=6,gridlines,frame,margin=(100,100,100,100)]')
  iw = winio@('%^pl&',gw,gh,20,x_data,y_data, draw_border)
  iw = winio@(' ')
  plot =2
end function plot 

integer function draw_border()
  call draw_rectangle@(100,100,gw-100,gh-100,rgb@(255,0,0))
  draw_border =2
end function draw_border

end module example
Back to top
View user's profile Send private message Visit poster's website
DanRRight



Joined: 10 Mar 2008
Posts: 2187
Location: South Pole, Antarctica

PostPosted: Wed May 20, 2020 9:52 pm    Post subject: Reply with quote

Thanks Paul and Ken,

Have not noticed your "frame" which is not the same as my used "framed" Smile

Is there a way to set the margin just for one specific (right, for example) axis? Then i will not change anything else in existing code (specifically not remove the pivot %pv to resize the plot with the mouse) and will know exactly the pixel position of the right axis while leaving pivot operational. I probably can do my own resizing with any arbitrary margin=(ix,iy,iz,it) but that will bend the idea of %pl to be a simple plotting utility into more complex territory

Paul, the additional function to know X and Y axis position which %pl chose as "nice numbers" instead of user defined x_min/x_max and y_min/y_max would be very nice. Without that whenever i plot anything on top of %pl, its position relative to any axis permanently changes with changing of plotted data and with pivot resize. Plotting mentioned above user own axis names, tics and captions
PaulLaidler wrote:

2. If an axis caption is not supplied then the defaults are lower case "x" and "y". Setting [x-axis=@] or [y-axis=@] prevents ClearWin+ from drawing the caption which could then be drawn using a callback function.
without such function is essentially impossible, the position relative to axis will permanently change

As to the
PaulLaidler wrote:

1. If ClearWin+ draws a title or axis caption at an inappropriate point then its position can be adjusted. For example [title=My Graph@(4.Cool] using a decimal point, draws "My Graph" at a point that is adjusted 4 pixels to the right and 8 pixels down from its default position.
i think that no one will ever object to set the default position of X and Y axis names at the center of axis. As a proof i made Google search images for "scientific graphs" and among numerous plots on the first page have not noticed any with not centered axis names
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 4 of 6

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group