## Duodecimal tickmarks?

Forum for PyNomo discussion.
jasonwalker
Posts: 27
Joined: Sun Sep 11, 2011 3:54 pm

### Duodecimal tickmarks?

Hi all,

Is it possible to create tickmarks in 12ths - for example, if I wanted tickmarks to represent years and months, or feet and inches?

thank you,

Jason
Leif
Posts: 56
Joined: Mon Dec 31, 2007 3:03 pm
Location: Finland
Contact:

### Re: Duodecimal tickmarks?

No. You need to use

'manual_axis_data'

as shown in http://pynomo.org/wiki/index.php?title=Examples_of_axes_parameters

br,

\leif
jasonwalker
Posts: 27
Joined: Sun Sep 11, 2011 3:54 pm

### Re: Duodecimal tickmarks?

I rather feared that was going to be the case. Never mind.

Jason.
NomoDave
Posts: 10
Joined: Wed Oct 05, 2011 2:36 pm

### Re: Duodecimal tickmarks?

Hi Jason / Hi Leif

I've been trying to find a solution for a similar problem this last few weeks.
I've been trying to write a Python routine which automatically generates tick marks of appropriate length to divide Hours into 5 minute intervals over any given user-definable range.

I eventually came up with a neat solution which doesn't rely on an inelegant list of IF-ELSE statements to generate tick marks of different lengths.

Cut & paste one of the examples below into Python 2.x , and enter any user-defined beginning and end points for your scale to see the output.

If you want a different number/arrangement of tick marks Jason, please post specific details and I'll try to write a modified routine for you.

I am only just getting started with both PyNomo and Python, so have not been brave enough to try to integrate these routines into PyNomo yet - maybe Leif or a more experienced programmer might be interested in taking this on? - but hopefully this is a good starting point.

Best wishes

Dave
(Swansea, UK)

------------------------------------------------------------

#DuoDecimal Tick Mark examples
#Dave Williams & Owen Bodger 3 Oct 2011
#For Python 2.x

#These examples make use of Python's modulus (%) and integer division (//) operators to generate a train of regularly
#repeating "pulses" of any given amplitude, phase, and frequency.
#Several such trains of pulses can then be summed together to give any combination of tick mark lengths/spacing
#over the desired range of values.
#It's a bit like making a complex curve out of component sine waves (Fourier or Harmonic Analysis); but here we're dealing with
#discreet rather than continuous values.

#It should be possible to adapt & incorporate these routines into PyNomo as required.

# Inches divided into 1/16th inch tick marks
InchStart = 0.25; InchStop = 1.5 # user defined beginning and end points for scale (Inches)
x = InchStart*16
while x <= InchStop*16:
print 'Inches: %.3f Tickmark length: %g'%(x/16.0,(1+((((x-1)%16)//15) + (((x-1)%8)//7) + (((x-1)%2)//1))))
x+=1

# Hours divided into 5min tick marks
HourStart = 1.5; HourStop = 3.25 #user defined beginning and end points for scale (Hours)
x = HourStart*12
while x<= HourStop*12:
print 'Hours: %.3f Tickmark length: %g'%((x/12.0),(1+(((x-1)%3)//2)+(((x-1)%6)//5)+(((x-1)%12)//11)))
x+=1

# Years divided into monthly tick marks
YearStart = 1.0; YearStop = 2.25 #user defined beginning and end points for scale (Years)
x = YearStart*12
while x<= YearStop*12:
print 'Years: %.3f Tickmark length: %g'%((x/12.0),(1+(((x-1)%2)//1)+(((x-1)%6)//5)+(((x-1)%12)//11)))
x+=1
NomoDave
Posts: 10
Joined: Wed Oct 05, 2011 2:36 pm

### Re: Duodecimal tickmarks?

Sorry; the formatting was lost when I cut and pasted the above examples from my Python editor to the discussion board.

The last two lines of code in each example (beginning "print..." and "x+=1") should both be indented 1 tab stop, otherwise the routines won't run.

Cheers

Dave
Leif
Posts: 56
Joined: Mon Dec 31, 2007 3:03 pm
Location: Finland
Contact:

### Re: Duodecimal tickmarks?

PyNomo uses 5 levels of ticks in scales. Default settings for these are (taken from nomo_axis.py)

Code: Select all

'text_distance_0':1.0,
'text_distance_1':1.0/4,
'text_distance_2':1.0/4,
'text_distance_3':1.0/4,
'text_distance_4':1.0/4,
'grid_length_0':3.0/4,
'grid_length_1':0.9/4,
'grid_length_2':0.5/4,
'grid_length_3':0.3/4,
'grid_length_4':0.2/4,
'text_size_0': text.size.small,
'text_size_1': text.size.scriptsize,
'text_size_2': text.size.tiny,
'text_size_3': text.size.tiny,
'text_size_4': text.size.tiny,
'text_size_log_0': text.size.small,
'text_size_log_1': text.size.tiny,
'text_size_log_2': text.size.tiny,

The reason for this introduction is, that one should define how different scalings should look like. For example we could have scale called hours:
- hours = level 0
- 10 minutes = level 1
- 5 minutes = level 2
- minutes = level 3
-10 seconds = level 4

Similarly one could have Year, month, day scalings. And foot inch scalings. These should be also made as smart scalings that avoids too dense ticks.

I propose that interested could make a proposal in this (hard coded) frame and I could try to implement these into pynomo. Because users is free to do his/her own clever scalings, not every possibility should be implemented. But I agree that there should be some most common ones.

br,

\leif
jasonwalker
Posts: 27
Joined: Sun Sep 11, 2011 3:54 pm

### Re: Duodecimal tickmarks?

Thanks for that Dave - quite an elegant solution. New to Python myself, so not entirely sure what's going on but I'll certainly give it a try. (Although a complex analysis exam followed by a family holiday are the first priorities!)

Jason

North Wales, as it happens.
NomoDave
Posts: 10
Joined: Wed Oct 05, 2011 2:36 pm

### Re: Duodecimal tickmarks?

Thanks both - glad to be able to help.

The way in which PyNomo reads instructions for tick mark style and length from a list is very intuitive for a human user.

However it might be difficult to adapt my routine to interface easily with this, as my routine is designed to be embedded within the main loop of code which produces all of the tick marks. Embedding my routine within the main code would require a knowledge of PyNomo which I don't have at present.

Also I agree, we also need to find a way of smart scaling the tick marks to prevent them from becoming too crowded.

I've got a lot of other work on at the moment, but will try to understand how PyNomo works a bit better, and see if I can join the two up somehow.

Any expert help you could give us Leif (or any other experienced PyNomo coders reading this) would be greatly appreciated.

My little routine is very compact, but as a consequence, it is not at all obvious how it works.
I'll try and explain how it works in more detail in another email when I get more time.

Have a great holiday Jason!

Best wishes

Dave
jasonwalker
Posts: 27
Joined: Sun Sep 11, 2011 3:54 pm

### Re: Duodecimal tickmarks?

Right. After what seems to be an age, I finally got round to tackling this. The nomogram which follows calculates a child's ideal body weight (what you should weigh) and lean body weight (what you would weigh without your fat) given the age, height and actual weight. An earlier version (without the duodecimal tickmarks on the agescale) of this was presented to a meeting of the Paediatric Anaesthesia Group of Wales (PAGW) last Autumn.

Everything is as I want it, apart from the fact that the manual tickmarks (on the age scale) are all the same length. I'm trying to get the 'quarter' marks longer than the twelfths, but they always come out the same size, no matter what.

Any ideas?

Jason

Code: Select all

"""
ideal wt z.py

With thanks to Leif Roschier for help with aligning the age scales.

"""
from pynomo.nomographer import *

### Definitions ###
def boys(age):
return (24-(8.75/(1+((age/14.7)**5.0))))

def girls(age):
return (22-(6.75/(1+((age/12.7)**6.0))))

def inv_girls(value):
return 12.7*(6.75/(22.0-value)-1.0)**(1.0/6.0)

def inv_boys(value):
return 14.7*(8.75/(24.0-value)-1.0)**(1.0/5.0)

###Age/weight block###

###3 line block

Boys1_para={
'tag':'Age',
'u_min':5,
'u_max':19,
'function':lambda age:boys(age),
'title':r'Age (years)',
'title_y_shift':0.8,
'tick_levels':1,
'tick_text_levels':1,
'tick_side':'left',
'scale_type':'linear smart',
'extra_params':[
{'tick_side':'left',
'scale_type':'manual line',
'line_length':0.25,
'manual_axis_data':
{6.50:'',
7.25:'',
7.50:'',
7.75:'',
8.25:'',
8.50:'',
8.75:'',
9.25:'',
9.50:'',
9.75:'',
10.25:'',
10.50:'',
10.75:'',
11.25:'',
11.50:'',
11.75:'',
12.25:'',
12.50:'',
12.75:'',
13.25:'',
13.50:'',
13.75:'',
14.25:'',
14.50:'',
14.75:'',
15.25:'',
15.50:'',
15.75:'',
16.25:'',
16.50:'',
16.75:'',
17.25:'',
17.50:'',
17.75:'',
18.25:'',
18.50:'',
18.75:'',
},
},
{'tick_side':'left',
'scale_type':'manual line',
'line_length':0.1,
'manual_axis_data':
{8.08333:'',
8.16667:'',
8.33333:'',
8.41667:'',
8.58333:'',
8.66667:'',
8.83333:'',
8.91667:'',
9.08333:'',
9.16667:'',
9.33333:'',
9.41667:'',
9.58333:'',
9.66667:'',
9.83333:'',
9.91667:'',
10.08333:'',
10.16667:'',
10.33333:'',
10.41667:'',
10.58333:'',
10.66667:'',
10.83333:'',
10.91667:'',
11.08333:'',
11.16667:'',
11.33333:'',
11.41667:'',
11.58333:'',
11.66667:'',
11.83333:'',
11.91667:'',
12.08333:'',
12.16667:'',
12.33333:'',
12.41667:'',
12.58333:'',
12.66667:'',
12.83333:'',
12.91667:'',
13.08333:'',
13.16667:'',
13.33333:'',
13.41667:'',
13.58333:'',
13.66667:'',
13.83333:'',
13.91667:'',
14.08333:'',
14.16667:'',
14.33333:'',
14.41667:'',
14.58333:'',
14.66667:'',
14.83333:'',
14.91667:'',
15.08333:'',
15.16667:'',
15.33333:'',
15.41667:'',
15.58333:'',
15.66667:'',
15.83333:'',
15.91667:'',
16.08333:'',
16.16667:'',
16.33333:'',
16.41667:'',
16.58333:'',
16.66667:'',
16.83333:'',
16.91667:'',
17.08333:'',
17.16667:'',
17.33333:'',
17.41667:'',
17.58333:'',
17.66667:'',
17.83333:'',
17.91667:'',
18.08333:'',
18.16667:'',
18.33333:'',
18.41667:'',
18.58333:'',
18.66667:'',
18.83333:'',
18.91667:'',
},
}],
'extra_titles':[
{'dx':-1.9,
'dy':0.3,
'width':5,
}]
}

Height_para={
'u_min':0.85,
'u_max':2,
'function':lambda u:u**2,
'title':r'Height (metres)',
'text_format':r"$%1.2f$",
'tick_levels':3,
'tick_text_levels':2,
'tick_side':'left',
}

Idealwt_para={
'tag':'wt',
'u_min':10,
'u_max':85,
'function':lambda u:(u),
'title':r'Ideal Weight (kg)',
'tick_levels':0,
'tick_text_levels':0,
'tick_side':'left',
}

block_1={
'block_type':'type_2',
'mirror_x':True,
'f1_params':Idealwt_para,
'f2_params':Height_para,
'f3_params':Boys1_para,
}

### Girls Scale ###
Girls_para={
'tag':'Age',
'u_min':5,
'u_max':19,
'function':lambda age:girls(age),
'align_func':lambda age:inv_boys(girls(age)),
'title':r'',
'tick_levels':1,
'tick_text_levels':1,
'tick_side':'right',
'title_x_shift':0.5,
'scale_type':'linear smart',
'extra_params':[
{'tick_side':'right',
'scale_type':'manual line',
'line_length':0.25,
'manual_axis_data':
{6.50:'',
7.25:'',
7.50:'',
7.75:'',
8.25:'',
8.50:'',
8.75:'',
9.25:'',
9.50:'',
9.75:'',
10.25:'',
10.50:'',
10.75:'',
11.25:'',
11.50:'',
11.75:'',
12.25:'',
12.50:'',
12.75:'',
13.25:'',
13.50:'',
13.75:'',
14.25:'',
14.50:'',
14.75:'',
15.25:'',
15.50:'',
15.75:'',
16.25:'',
16.50:'',
16.75:'',
17.25:'',
17.50:'',
17.75:'',
18.25:'',
18.50:'',
18.75:'',
},
},
{'tick_side':'right',
'scale_type':'manual line',
'line_length':0.1,
'manual_axis_data':
{8.08333:'',
8.16667:'',
8.33333:'',
8.41667:'',
8.58333:'',
8.66667:'',
8.83333:'',
8.91667:'',
9.08333:'',
9.16667:'',
9.33333:'',
9.41667:'',
9.58333:'',
9.66667:'',
9.83333:'',
9.91667:'',
10.08333:'',
10.16667:'',
10.33333:'',
10.41667:'',
10.58333:'',
10.66667:'',
10.83333:'',
10.91667:'',
11.08333:'',
11.16667:'',
11.33333:'',
11.41667:'',
11.58333:'',
11.66667:'',
11.83333:'',
11.91667:'',
12.08333:'',
12.16667:'',
12.33333:'',
12.41667:'',
12.58333:'',
12.66667:'',
12.83333:'',
12.91667:'',
13.08333:'',
13.16667:'',
13.33333:'',
13.41667:'',
13.58333:'',
13.66667:'',
13.83333:'',
13.91667:'',
14.08333:'',
14.16667:'',
14.33333:'',
14.41667:'',
14.58333:'',
14.66667:'',
14.83333:'',
14.91667:'',
15.08333:'',
15.16667:'',
15.33333:'',
15.41667:'',
15.58333:'',
15.66667:'',
15.83333:'',
15.91667:'',
16.08333:'',
16.16667:'',
16.33333:'',
16.41667:'',
16.58333:'',
16.66667:'',
16.83333:'',
16.91667:'',
},
}]
}

Girls_block={
'block_type':'type_8',
'f_params':Girls_para
}
### Weights block###
Idealwt_para2={
'tag':'wt',
'u_min':10,
'u_max':85,
'function':lambda u:0.71*u,
'title':r'',
'tick_levels':3,
'tick_text_levels':2,
'tick_side':'right',
}

Actual_wt={
'u_min':10,
'u_max':185,
'function':lambda u:0.29*u,
'title':r'Actual Weight (kg)',
'tick_levels':3,
'tick_text_levels':2,
'tick_side':'left',
}

Lean_wt={
'u_min':10,
'u_max':115,
'function':lambda u:-(u),
'title':r'Lean Body Mass (kg)',
'tick_levels':3,
'tick_text_levels':2,
'tick_side':'right',
}
block_2={
'block_type':'type_1',
'f1_params':Idealwt_para2,
'f2_params':Lean_wt,
'f3_params':Actual_wt,
}
main_params={
'filename':'Body mass nomo1.pdf',
'paper_height':20.0,
'paper_width':30.0,
'block_params':[block_1,Girls_block,block_2],
'transformations':[('scale paper',)],
}
Nomographer(main_params)

Leif
Posts: 56
Joined: Mon Dec 31, 2007 3:03 pm
Location: Finland
Contact:

### Re: Duodecimal tickmarks?

Hello Jason,

For manual axis you can use parameters:
'text_distance_1' and 'grid_length_1'

to set text distance and tick marks length. Text size can be set with

'text_size_manual'

br,

\leif
jasonwalker
Posts: 27
Joined: Sun Sep 11, 2011 3:54 pm

### Re: Duodecimal tickmarks?

Thanks Leif!

I'll let you know how I get on.

Jason

jasonwalker
Posts: 27
Joined: Sun Sep 11, 2011 3:54 pm

### Re: Duodecimal tickmarks?

It worked!!!

Will post the finished product when I've finished tweaking the 'look'!

Thanks everyone.
cjltuk
Posts: 1
Joined: Fri May 10, 2013 1:37 am

### Re: Duodecimal tickmarks?

I have just been introduced to Pynomo via a friend of Ron Doerfler. My field is sundials, so I was particularly interested in the solution of spherical triangles. To that end I have extended his nomogram that uses the cosine rule and created a sine rule nomogram that is much simpler than the one in Ron's book on Pynomo. I have also created a nomogram to find the true proportions of an object given only a perspective photograph.

But the units are degrees and minutes, so I looked into Pynomo to add units that are not measured in decades, such as hours/minutes/seconds, degrees/minutes/seconds, feet/inches, lbs/ozs,...

I have achieved this by extending the scale types supported in nomo_axis.py. So far, I have only done hh:mm:ss and degrees ^\circ mm'ss". In the nomogram file you just put 'scale_type':'hhmmss' or 'scale_type':'ddmmss'. I haven't yet done a 'smart' version or log versions. Adding, say, lbs/oz would be trivial but means editing nomo_axis.py.

I don't know how to offer this back to the community. Can anyone tell me?

Chris Lusby Taylor
Newbury
England
Glen
Posts: 67
Joined: Fri Jan 25, 2008 4:11 am
Location: Australia

### Re: Duodecimal tickmarks?

[quote="cjltuk"]I don't know how to offer this back to the community. Can anyone tell me?[/quote]

Leif would probably be better placed to answer this but I think the two possible routes are either to see if Leif wants to incorporate your code or to fork the code. If it was on Github you could do a pull request, but I don't know how to do the equivalent on Sourceforge (if it can be done).