 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Sun Nov 19, 2023 6:05 am Post subject: first time user of %PL |
|
|
After watching for a long time, I have had a need to look at many (400) time history plots that I have generated in my FE analysis.
I thought I should put a %PL routine in my results analysis to see how it was going.
I found an example of Ken's posts from Oct 2017 and give it a go.
To do and review 400 plots, I converted Ken's program to a subroutine which would be called multiple times.
It has worked very well, but I wanted to improve, by giving each plot a title and dumping to a .png file.
I included %ws for the title (first at the top, then at the bottom) and
%mn for a screen_dump_func to dump the graphics region to a .png file.
The problem I have is export_image@ only appears to grab the %PL region, but not the added text above/below. Puzzling !
How can get the %ws (or text) to be included in the export_image@ region?
Basically I want to annotate the plot.
Code: | ! C:\temp\forum\danR\ken.f90 24/10/2017
subroutine plot_test ( x, y, npts, message )
implicit none
include<windows.ins>
integer npts
real(kind=2) x(npts), y(npts)
character message*(*)
integer i, t, b, l, r
integer, external :: Screen_dump_func
i = winio@ ('%ww[no_border]%ca[Fastener Force History]&')
!z i = winio@ ('%pv&')
i = winio@ ('%mn[Exit]&','exit')
i = winio@ ('%mn[&Dump]&', Screen_dump_func)
i = winio@ ('%fn[Tahoma]&')
i = winio@ ('%ts&', 1.5d0)
!z i = winio@ ('%ws%nl&', trim (message) ) !, xs, ys, rgb@ (255,0,0))
call winop@ ('%pl[native,x_array,N_GRAPHS=1]')
call winop@ ('%pl[y_min=-30,y_max=10,x_min=0,x_max=7.2]')
call winop@ ('%pl[link=lines, colour=blue, symbol=0, pen_style=0]')
t = 50 ; b = 50 ; l = 75 ; r = 45
call set_pl_margins (t,b,l,r) !top, bottom, left, right
i = winio@ ('%`bg[white]&')
i = winio@ ('%pl&',1300,900,npts,x,y)
i = winio@ ('%ff%ws', trim (message) ) !, xs, ys, rgb@ (255,0,0))
end subroutine plot_test
subroutine set_pl_margins(top, bottom, left, right)
include<windows.ins>
integer, intent(in) :: top, bottom, left, right
character(len=5), parameter :: fmt1 = '(I5)'
character(len=5) t_txt, b_txt, l_txt, r_txt
character(len=12):: start_str = '%pl[margin=('
character(len=2 ):: end_str = ')]'
character(len=80) str
write(t_txt,fmt1) top ; write(b_txt,fmt1) bottom
write(l_txt,fmt1) left ; write(r_txt,fmt1) right
! Call to %pl[margin...] is left, top, right, bottom
str = start_str//trim(adjustl(l_txt))//','&
//trim(adjustl(t_txt))//','&
//trim(adjustl(r_txt))//','&
//trim(adjustl(b_txt))//end_str
! write(*,*) str
call winop@(str)
end subroutine set_pl_margins
integer*4 function Screen_Dump_func ()
!
! dumps screen to a pcx file
!
character message*50, prefix*50
!
prefix = 'fastener_dump_'
!
call Dump_png_func (message, prefix, '.png') ! uses export_image@ (file_png)
!
write (*,*) ' Exiting Screen_Dump_func ', trim (message)
Screen_Dump_func = 2
return
end function Screen_Dump |
|
|
Back to top |
|
 |
PaulLaidler Site Admin

Joined: 21 Feb 2005 Posts: 7766 Location: Salford, UK
|
Posted: Sun Nov 19, 2023 9:15 am Post subject: |
|
|
John
Try using DRAW_CHARACTERS@ and its associated routines that set the font etc. Also GET_PLOT_POINT@ can be used to get the pixel coordinates of a particular point relative to the axes. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Sun Nov 19, 2023 10:17 am Post subject: |
|
|
Thanks Paul,
I did do some more reading of the documentation and found that using %^PL is demonstrated as a way to include a call to draw_characters@ ( trim(plot_desc), lx, ly, 0 ) in the region, via a call-back "Legend".
I created a module for key data, the title and integer function draw_legend ().
So I think I have a solution.
I also call plot test about 80 times, so this repeated definition of a clearwin %PL region does not cause any noticeable problems.
I have workable code for applying the title and a screen dump, if needed. |
|
Back to top |
|
 |
Kenneth_Smith

Joined: 18 May 2012 Posts: 682 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Sun Nov 19, 2023 11:38 am Post subject: |
|
|
John,
If a single title above the plot is sufficient, the quickest solution would be something like:
Code: | use clrwin
implicit none
character(len=120) :: title
integer, parameter :: n = 10
integer i
real*8 :: x(n) = [(i, i=1,n)], y(n) = [(i**2,i=1,n)]
title = 'Plot 1'
i = winio@('%fn[Tahoma]%bf&')
call winop@('%pl[native,x_array,n_graphs=1,framed]')
call winop@('%pl[Title="'//trim(adjustl(title))//'"]')
i = winio@('%pl',600,400,n,x,y)
title = 'Plot 2'
i = winio@('%fn[Tahoma]%bf&')
call winop@('%pl[native,x_array,n_graphs=1,framed]')
call winop@('%pl[Title="'//trim(adjustl(title))//'"]')
i = winio@('%pl',600,400,n,x,y)
end |
|
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Mon Nov 20, 2023 5:43 am Post subject: |
|
|
Hi Ken,
Thanks for your advice and your earlier posted examples, which were very helpful.
I was unsure where the latest documentation is located. I found recent via Plato Help > ClearWin+.
%PL is not included in "Alphabetical index of format codes" ?
My understanding is that :
FTN95 /64 %PL is the "native mode" with the recently developed options, while,
FTN95 (/32) %PL uses the Simpleplot .dll version.
Having now found "Native graph plotting" and code example of %^PL, I can now include annotation in the %PL plotting region and dump my enhanced plots to a .png file for inclusion in reports.
It was helpful to easily include this plot capability in a Fortran program that generates 400 force functions so they can be systematically reviewed, rather than attacking the logistics of loading them all into Excel. |
|
Back to top |
|
 |
PaulLaidler Site Admin

Joined: 21 Feb 2005 Posts: 7766 Location: Salford, UK
|
Posted: Mon Nov 20, 2023 8:19 am Post subject: |
|
|
John
The %pl "native" options are also available for 32 bit programming. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Wed Nov 22, 2023 2:56 am Post subject: |
|
|
Paul, thanks for the update , I will have to understand this better.
I thought %pl "native" was a Silverfrost replacement for changes to SimplePlot, which was no longer being developed.
Can you direct me to where I might be able to read more details ?
Although I am only using FTN95 /64 for this graphics. |
|
Back to top |
|
 |
PaulLaidler Site Admin

Joined: 21 Feb 2005 Posts: 7766 Location: Salford, UK
|
Posted: Wed Nov 22, 2023 8:34 am Post subject: |
|
|
John
The native %pl was introduced because SIMPLEPLOT is a third party 32 bit library. So the development was motivated by the move to 64 bits. But the native %pl soon had more options that work equally well for 32 bits.
Documentation can be found the the FTN95 help file and in Silverfrost\FTN95\doc\cwplus.enh both of which can be accessed from the Plato Help menu. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Fri Nov 24, 2023 10:53 am Post subject: |
|
|
Thanks for the advice, however I am now wanting to plot multiple (4) lines on a chart.
I am assumed this could be achieved by providing a 2d Y array, but can't find it described ? ie N_GRAPH=4:
integer npts, ng
real*8 x(npts), y(npts,ng)
...
call winop@ ('%pl[native,x_array,N_GRAPHS=4]')
call winop@ ('%pl[y_min=-12,y_max=2,x_min=0,x_max=7.2]')
...
call winop@ ('%pl[link=lines, colour=blue, symbol=0, pen_style=0]')
i = winio@ ('%`bg[white]&')
i = winio@ ('%^pl',x_size,y_size, npts,x,y, draw_legend)
Code: | subroutine plot_test ( x, y, npts, ng, message )
! draw either 1 or 4 (ng=4) graphs
use plot_info ! integer x_size, y_size
implicit none
include<windows.ins>
integer npts, ng
real*8 x(npts), y(npts,ng)
character message*(*)
integer i
integer, external :: Screen_dump_func
x_size = 1300
y_size = 900
plot_desc = message
i = winio@ ('%ww[no_border]%ca[Fastener Force History]&')
i = winio@ ('%mn[Exit]&','exit')
i = winio@ ('%mn[&Dump]&', Screen_dump_func)
i = winio@ ('%fn[Tahoma]&')
i = winio@ ('%ts&', 1.5d0)
if ( ng == 1 ) then
call winop@ ('%pl[native,x_array,N_GRAPHS=1]')
call winop@ ('%pl[y_min=-12,y_max=2,x_min=0,x_max=7.2]')
else
call winop@ ('%pl[native,x_array,N_GRAPHS=4]')
call winop@ ('%pl[y_min=-12,y_max=2,x_min=0,x_max=7.2]')
end if
call winop@ ('%pl[x_axis=Time(Seconds)]')
call winop@ ('%pl[y_axis=Axle_disp(m)]')
call winop@ ('%pl[link=lines, colour=blue, symbol=0, pen_style=0]')
i = winio@ ('%`bg[white]&')
i = winio@ ('%^pl',x_size,y_size, npts,x,y, draw_legend) ! assume Y(npts,NG) provided ??
end subroutine plot_test
|
Can someone please explain |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Fri Nov 24, 2023 11:04 am Post subject: |
|
|
I got the following to work.
Is it correct, but is there a neater way ?
Is there any advice on the order required for winop@ and winio@ ?
Code: | subroutine plot_test ( x, y, npts, ng, message )
! draw either 1 or 4 (ng=4) graphs
use plot_info
implicit none
include<windows.ins>
integer npts, ng
real*8 x(npts), y(npts,ng)
character message*(*)
integer i, t, b, l, r !, xs, ys
integer, external :: Screen_dump_func
real*8 :: y1(npts), y2(npts), y3(npts), y4(npts)
integer*4 :: k
x_size = 1300
y_size = 900
plot_desc = message
i = winio@ ('%ww[no_border]%ca[Fastener Force History]&')
!z i = winio@ ('%pv&')
i = winio@ ('%mn[Exit]&','exit')
i = winio@ ('%mn[&Dump]&', Screen_dump_func)
i = winio@ ('%fn[Tahoma]&')
i = winio@ ('%ts&', 1.5d0)
if ( ng == 1 ) then
call winop@ ('%pl[native,x_array,N_GRAPHS=1]')
call winop@ ('%pl[y_min=-12,y_max=2,x_min=0,x_max=7.2]')
call winop@ ('%pl[x_axis=Time(Seconds)]')
call winop@ ('%pl[y_axis=Axle_disp(m)]')
else
call winop@ ('%pl[native,x_array,N_GRAPHS=4]')
call winop@ ('%pl[y_min=-12,y_max=2,x_min=0,x_max=7.2]')
call winop@ ('%pl[x_axis=Time(Seconds)]')
call winop@ ('%pl[y_axis=Axle_disp(m)]')
end if
call winop@ ('%pl[link=lines, colour=blue, symbol=0, pen_style=0]')
t = 50 ; b = 50 ; l = 75 ; r = 45
call set_pl_margins (t,b,l,r) !top, bottom, left, right
i = winio@ ('%`bg[white]&')
if ( ng == 1 ) then
i = winio@ ('%^pl',x_size,y_size, npts,x,y, draw_legend)
else
do k = 1,npts
y1(k) = y(k,1)
y2(k) = y(k,2)
y3(k) = y(k,3)
y4(k) = y(k,4)
end do
i = winio@ ('%^pl',x_size,y_size, npts,x,y1,y2,y3,y4, draw_legend)
end if
end subroutine plot_test
|
|
|
Back to top |
|
 |
Kenneth_Smith

Joined: 18 May 2012 Posts: 682 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Nov 24, 2023 11:53 am Post subject: |
|
|
For N_GRAPHS=4, use the [independent] option, now npts is an array npts=[n1,n2,n3,n4] where n# is the number of points per curve.
You must now supply a pair of arrays (x(n1) and y(n1) etc.) for each line.
You can hide any of the individual plots by setting the corresponding element of npts to zero.
So to draw only the first curve npts=[n1,0,0,0]. i.e you don't need two different calls to %pl to set up the two different plots. |
|
Back to top |
|
 |
Kenneth_Smith

Joined: 18 May 2012 Posts: 682 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Nov 24, 2023 12:23 pm Post subject: |
|
|
This demonstrates the basic idea.
Code: | use clrwin
implicit none
integer, parameter :: n = 100
real*8, parameter :: pi = 4.d0*atan(1.d0)
real*8, parameter :: twoPi = 2.d0*pi
real*8 :: x(n), y1(n), y2(n), y3(n), y4(n)
integer :: i, iw, npl(4)
x = [( 0.d0 + twoPi/dble(n) * (i-1), i=1,n,1 )]
y1 = sin(x)
y2 = sin(x + pi/6.d0)
y3 = sin(x + 2*pi/6.d0)
y4 = sin(x + 3*pi/6.d0)
npl = [n,0,0,0] ! Plot y1 only
iw = winio@('%fn[Consolas]%ts&',1.5d0)
call winop@('%pl[native,independent,x_array,n_graphs=4,frame,width=2]')
iw = winio@('%pl',800,600,npl, x, y1, x, y2, x, y3, x, y4)
npl = [0,0,0,n] ! Plot y4 only
iw = winio@('%fn[Consolas]%ts&',1.5d0)
call winop@('%pl[native,independent,x_array,n_graphs=4,frame,width=2]')
iw = winio@('%pl',800,600,npl, x, y1, x, y2, x, y3, x, y4)
npl = [n,n,n,n] ! Plot y1 to y4
iw = winio@('%fn[Consolas]%ts&',1.5d0)
call winop@('%pl[native,independent,x_array,n_graphs=4,frame,width=2]')
iw = winio@('%pl',800,600,npl, x, y1, x, y2, x, y3, x, y4)
end
|
|
|
Back to top |
|
 |
Kenneth_Smith

Joined: 18 May 2012 Posts: 682 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Nov 24, 2023 1:24 pm Post subject: |
|
|
And it then becomes very easy to make the selection of which graphs to plot interactive:
Code: | module data_mod
integer, parameter :: n = 100
real*8, parameter :: pi = 4.d0*atan(1.d0)
real*8, parameter :: twoPi = 2.d0*pi
real*8 :: x(n), y1(n), y2(n), y3(n), y4(n)
integer :: npl(4), stat(4) = [1,0,0,0]
end module data_mod
program p
use clrwin
use data_mod
implicit none
integer :: i, iw
integer :: update ; external update
x = [( 0.d0 + twoPi/dble(n) * (i-1), i=1,n,1 )]
y1 = sin(x)
y2 = sin(x + pi/6.d0)
y3 = sin(x + 2*pi/6.d0)
y4 = sin(x + 3*pi/6.d0)
npl = n*stat
iw = winio@('%fn[Consolas]%ts&',1.5d0)
call winop@('%pl[native,independent,x_array,n_graphs=4,frame,width=2]')
iw = winio@('%2.1ob[invisible]%pl%cb&',800,600,npl, x, y1, x, y2, x, y3, x, y4)
iw = winio@('%rb[y1]%nl%rb[y2]%nl%rb[y3]%nl%rb[y4]&',stat(1),stat(2),stat(3),stat(4))
iw = winio@('%dl&',1.d0,update)
iw = winio@('%cb')
end program p
integer function update()
use data_mod
use clrwin
npl = n*stat
call simpleplot_redraw@()
update = 2
end function update
|
|
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2502 Location: Sydney
|
Posted: Fri Nov 24, 2023 2:02 pm Post subject: |
|
|
Hi Ken,
Thanks for these examples.
I am struggling with a large set of results, so I am looking to give Excel away and write a Fortran program that can better manage all the different results.
I am modelling a train crossing a set of girders, so have an analysis that generates a time varying force function for each rail fastener.
I then take each fastener time force function and introduce this into a time history analysis for all these force functions.
Conceptually it is fairly simple, but logistically the data transfer files are huge, so I want a more systematic approach than what Excel can provide.
At the end, I have to pick out the important results from many, for which %PL may be challenging, if I want to compare "n" graphs !
Thanks for your assistance so far and I will keep asking the questions. |
|
Back to top |
|
 |
Kenneth_Smith

Joined: 18 May 2012 Posts: 682 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Nov 24, 2023 4:54 pm Post subject: |
|
|
John,
If n_graphs is going to become a very large number, then you should look at the %pl option [link=user] and set_plot_mode@ which allow the graphs to be drawn via the call back.
Code: | module data_mod
integer, parameter :: n = 10
real*8 :: x(n) = [(i, i=1,n)], y(n) = [(i**1.5d0,i=1,n)], y2(n) = [(i**2,i=1,n)]
end data_mod
program plot_mode
use clrwin
use data_mod
implicit none
integer i
integer pl_cb ; external pl_cb
i = winio@('%ww%fn[Consolas]%ts%bf&',1.5d0)
call winop@('%pl[x_array,link=user,frame,gridlines]')
call winop@('%pl[x_min=0,x_max=10,dx=2, y_min=0,y_max=100,dy=20]')
i = winio@('%pv%^pl', 1200, 800, 2, dble([0,1]), dble([0,1]), pl_cb )
end program plot_mode
integer function pl_cb()
use clrwin
use data_mod
character(len=30) :: CLEARWIN_STRING@
character(len=30) :: cb_reason
cb_reason = CLEARWIN_STRING@('CALLBACK_REASON')
if (cb_reason .eq. "PLOT_ADJUST") then
call set_plot_mode@(1)
call set_line_width@(2)
call draw_curvesd@(x,y,n,rgb@(255,0,0))
call draw_symbolsd@(x,y,n,11,4,rgb@(255,0,0))
call draw_curvesd@(x,y2,n,rgb@(0,0,255))
call draw_symbolsd@(x,y2,n,11,4,rgb@(0,0,255))
call set_plot_mode@(0)
end if
pl_cb = 2
end function pl_cb |
|
|
Back to top |
|
 |
|
|
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
|