Doubts and equation "problems"

Forum for PyNomo discussion.
ana_ferro
Posts: 1
Joined: Tue Aug 07, 2012 4:39 pm

Doubts and equation "problems"

Postby ana_ferro » Wed Aug 08, 2012 2:58 pm

Hi!
I'm Ana, a portuguese Public Health Master student and i was hoping you could help me with my tiny problem.
I beg your pardon for intruding in this forum but i'm new with Pynomo Software and, although i don't think it's dificult to work with it, i'm having a lot of trouble with creating a nomogram that relates pre and posttest probability with likelihood ratio.
I would like to create a simple nomogram (a much much more simple nomogram than this http://www.myreckonings.com/modernnomograms/Doc_What_Are_My_Chances_UMAP_32-4-2011.pdf), with three scales, kinda like type 1 example, but i'm not able to transform my equation into the formula that this type allows.
So, my question is: how i put this formula

LR=[ProbPret x (1-ProbPost)]/[(1-ProbPret) x ProbPost]

into a type1? Or what is the nomogram script that will allow me to draw this equation?
I know that my doubt has more to do with maths that with the software itself, but if you could help that would speed up my job.


Thank you very much!

Ana
RonDoerfler
Posts: 27
Joined: Mon Feb 04, 2008 9:43 pm
Location: USA
Contact:

Re: Doubts and equation "problems"

Postby RonDoerfler » Thu Aug 16, 2012 7:21 pm

Hi Ana,

The more complicated circular nomogram for Bayes' Theorem that you reference was actually designed by Leif Roschier (the PyNomo author and host of this forum), Joe Marasco and myself. To create a simpler Type 1 nomogram of three parallel scales like the original 1975 Fagan Nomogram for Bayes' Theorem, you need to convert the equation for LR into a sum of functions of each variable. Logarithms can be used to convert multiplications and divisions into additions and subtractions, and it turns out that we can separate the terms into such a sum:

LR = posttestodds / prettestodds

but odds = Probability/(1-Probability), so

LR = [postestprob/(1-postestprob)] / [pretestprob/(1-pretestprob)]

Rearranging this produces your equation but with posttestprob and pretestprob swapped. I believe this is the correct version.

We can take the logs of both sides, where log(a/b) = log a - log b, and get

log LR = log [postestprob/(1-postestprob)] - log [pretestprob/(1-pretestprob)]

or, again since log(a/b) = log a - log b,

log LR = log(postestprob) - log (1-postestprob) - log (pretestprob) + log (1-pretestprob)

which can be rearranged as the sum of functions of each variable in the order that we want the scales to be:

-log (pretestprob) + log (1-pretestprob) - log LR + log(postestprob) - log (1-postestprob) = 0

where the three scales of the Type 1 nomogram have the functions:

- log(pretestprob) + log (1-pretestprob)
- log LR
log (postestprob) - log (1-postestprob)

The code below will draw this nomogram. I've included grid_length parameters to make the minor tick marks longer, as they are very short otherwise. If you remove or comment out the isopleth_values parameter line the sample isopleth will not be drawn on the nomogram.

Code: Select all

### FaganNomogramFinerResolution_081512v1.py ###

# posttestodds = LR x pretestodds
# or log(posttestodds) - log(LR) - log(pretestodds) = 0
# odds = P/(1-P) so log(odds) = log(P) - log(1-P)

from pynomo.nomographer import *

PretestProb_params={
        'u_min':0.1,
        'u_max':99.0,
        'function':lambda u:-log10(u/100.0) + log10(1.0-u/100.0),
        'title':r'\large Pre-Test Probability (\%)',
        'title_y_shift':0.7,
        'tick_levels':4,
        'tick_text_levels':2,
        'scale_type':'log smart',
        'tick_side':'left',
        # Custom tick mark lengths
        'grid_length_0':0.75,
        'text_distance_0':0.85,
        'grid_length_1':0.4,
        'text_distance_1':0.5,
        'grid_length_2':0.25,
        'text_distance_2':0.35,
        'grid_length_3':0.2,
        'text_distance_3':0.3,
        'grid_length_4':0.15,
        'text_distance_4':0.25,
                }

PosttestProb_params={
        'u_min':0.1,
        'u_max':99.0,
        'function':lambda u:log10(u/100.0) - log10(1.0-u/100.0),
        'title':r'\large Post-Test Probability (\%)',
        'title_y_shift':0.7,
        'tick_levels':5,
        'tick_text_levels':2,
        'scale_type':'log smart',
        # Custom tick mark lengths
        'grid_length_0':0.75,
        'text_distance_0':0.85,
        'grid_length_1':0.4,
        'text_distance_1':0.5,
        'grid_length_2':0.25,
        'text_distance_2':0.35,
        'grid_length_3':0.2,
        'text_distance_3':0.3,
        'grid_length_4':0.15,
        'text_distance_4':0.25,
                }

LR_params={
        'u_min':0.0005,
        'u_max':2000.0,
        'function':lambda u:-log10(u),
        'title':r'\large Likelihood Ratio',
        'title_y_shift':0.7,
        'tick_levels':5,
        'tick_text_levels':2,
        'scale_type':'log smart',
        # Custom tick mark lengths
        'grid_length_0':0.75,
        'text_distance_0':0.85,
        'grid_length_1':0.4,
        'text_distance_1':0.5,
        'grid_length_2':0.25,
        'text_distance_2':0.35,
        'grid_length_3':0.2,
        'text_distance_3':0.3,
        'grid_length_4':0.15,
        'text_distance_4':0.25,
                }

block_1_params={
        'block_type':'type_1',
        'f1_params':PretestProb_params,
        'f2_params':LR_params,
        'f3_params':PosttestProb_params,
        'isopleth_values':[[40.0,5.0,'x']],
               }

main_params={
        'filename':'FaganNomogramFinerResolution_081512v1.pdf',
        'paper_height':18.0,
        'paper_width':12.0,
        'block_params':[block_1_params],
        'transformations':[('rotate',0.01),('scale paper',),
             ('polygon',)],
        'title_y':-1.0,
        'title_box_width': 5.0,
        'title_str':r'\Large Fagan Nomogram',
        'isopleth_params':[
             {'color':'Red',
              'linewidth':'thin',
              'linestyle':'dashed',
              'circle_size':0.08,
              'transparency':0.0,
             },
           ],
               }
Nomographer(main_params)

If you want a more uncluttered version that looks just like the original Fagan Nomogram, you can specify which individual tick marks to include. Here the tick marks are added to both sides of the scales, with the labels only on one side, so the tick marks run through the scales. Note that there are some versions of Fagan's Nomogram on the web and in print that incorrectly show the end values on the middle scale shifted outward.

Code: Select all

### FaganNomogram_081512v1.py ###

# posttestodds = LR x pretestodds
# or log(posttestodds) - log(LR) - log(pretestodds) = 0
# odds = P/(1-P) so log(odds) = log(P) - log(1-P)

from pynomo.nomographer import *

PretestProb_params={
        'u_min':0.1,
        'u_max':99.0,
        'function':lambda u:-log10(u/100.0) + log10(1.0-u/100.0),
        'title':r'\Large Pre-Test Probability (\%)',
        'title_y_shift':0.7,
        'tick_levels':3,
        'tick_text_levels':1,
        'scale_type':'manual line',
        'manual_axis_data': {
              0.1:'0.1',
              0.2:'0.2',
              0.3:'0.3',
              0.5:'0.5',
              1.0:'1',
              2.0:'2',
              5.0:'5',
              10.0:'10',
              20.0:'20',
              30.0:'30',
              40.0:'40',
              50.0:'50',
              60.0:'60',
              70.0:'70',
              80.0:'80',
              90.0:'90',
              95.0:'95',
              98.0:'98',
              99.0:'99',
           },
        'tick_side':'left',
      'extra_params':[{
        'tick_side':'right',
        'scale_type':'manual line',
        'manual_axis_data': {
              0.1:'',
              0.2:'',
              0.3:'',
              0.5:'',
              1.0:'',
              2.0:'',
              5.0:'',
              10.0:'',
              20.0:'',
              30.0:'',
              40.0:'',
              50.0:'',
              60.0:'',
              70.0:'',
              80.0:'',
              90.0:'',
              95.0:'',
              98.0:'',
              99.0:'',
           },
              }],
                }

PosttestProb_params={
        'u_min':0.1,
        'u_max':99.0,
        'function':lambda u:log10(u/100.0) - log10(1.0-u/100.0),
        'title':r'\Large Post-Test Probability (\%)',
        'title_y_shift':0.7,
        'tick_levels':3,
        'tick_text_levels':1,
        'scale_type':'manual line',
        'manual_axis_data': {
              0.1:'0.1',
              0.2:'0.2',
              0.3:'0.3',
              0.5:'0.5',
              1.0:'1',
              2.0:'2',
              5.0:'5',
              10.0:'10',
              20.0:'20',
              30.0:'30',
              40.0:'40',
              50.0:'50',
              60.0:'60',
              70.0:'70',
              80.0:'80',
              90.0:'90',
              95.0:'95',
              98.0:'98',
              99.0:'99',
           },
        'tick_side':'left',
      'extra_params':[{
        'tick_side':'right',
        'scale_type':'manual line',
        'manual_axis_data': {
              0.1:'',
              0.2:'',
              0.3:'',
              0.5:'',
              1.0:'',
              2.0:'',
              5.0:'',
              10.0:'',
              20.0:'',
              30.0:'',
              40.0:'',
              50.0:'',
              60.0:'',
              70.0:'',
              80.0:'',
              90.0:'',
              95.0:'',
              98.0:'',
              99.0:'',
           },
              }],
                }

LR_params={
        'u_min':0.0005,
        'u_max':2000.0,
        'function':lambda u:-log10(u),
        'title':r'\Large Likelihood Ratio',
        'title_y_shift':0.7,
        'tick_levels':3,
        'tick_text_levels':1,
        'scale_type':'manual line',
        'manual_axis_data': {
              0.0005:'0.0005',
              0.001:'0.001',
              0.002:'0.002',
              0.005:'0.005',
              0.01:'0.01',
              0.02:'0.02',
              0.05:'0.05',
              0.1:'0.1',
              0.2:'0.2',
              0.5:'0.5',
              1.0:'',
              2.0:'',
              5.0:'',
              10.0:'',
              20.0:'',
              50.0:'',
              100.0:'',
              200.0:'',
              500.0:'',
              1000.0:'',
              2000.0:'',
           },
      'extra_params':[{
        'tick_side':'left',
        'scale_type':'manual line',
        'manual_axis_data': {
              0.0005:'',
              0.001:'',
              0.002:'',
              0.005:'',
              0.01:'',
              0.02:'',
              0.05:'',
              0.1:'',
              0.2:'',
              0.5:'',
              1.0:'1',
              2.0:'2',
              5.0:'5',
              10.0:'10',
              20.0:'20',
              50.0:'50',
              100.0:'100',
              200.0:'200',
              500.0:'500',
              1000.0:'1000',
              2000.0:'2000',
           },
              }],
                }

block_1_params={
        'block_type':'type_1',
        'f1_params':PretestProb_params,
        'f2_params':LR_params,
        'f3_params':PosttestProb_params,
        'isopleth_values':[[40.0,5.0,'x']],
               }

main_params={
        'filename':'FaganNomogram_081512v1.pdf',
        'paper_height':16.0,
        'paper_width':8.0,
        'block_params':[block_1_params],
        'transformations':[('rotate',0.01),('scale paper',),
             ('polygon',)],
        #'title_x':0.0,
        'title_y':-1.0,
        'title_box_width': 5.0,
        'title_str':r'\Large Fagan Nomogram',
      'isopleth_params':[
           {'color':'Red',
            'linewidth':'thin',
            'linestyle':'dashed',
            'circle_size':0.08,
            'transparency':0.0,
           },
           ],
               }
Nomographer(main_params)

Ron

Return to “PyNomo”

Who is online

Users browsing this forum: No registered users and 3 guests