Menu

callback functions

Tarskin
2012-12-12
2012-12-13
  • Tarskin

    Tarskin - 2012-12-12

    Dear All,

    I am trying to use the callback functionality of PHPlot to annotate data retrieved from 1 query set (yielding a thinbar plot) with data retrieved from a different query. I have so far succeeded in placing my annotation at the correct X-coords with the correct label (both acquired from the 'different query' performed inside of the callback function) but am struggling with retrieving the correct Y-coords.

    I was wondering if there is any way to pass additional parameters (like the results from the original query) to a callback function so that I can write a small matching routine inside the callback function?

    Thanks in advance,
    Bas Jansen

    PS: A rough schematic representation of my code is as follows

    1. Retrieve X/Y dataset from DB
    2. callback function definition (retrieves X/label dataset from DB, currently places label at a predetermined height)
    3. Plot X/Y data as thin bar plot
    4. perform callback function
    5. drawgraph
     
  • lbayuk

    lbayuk - 2012-12-12

    Each callback function is called by PHPlot with a second argument that you specify when you register the callback. This is the passthru or arg argument in the documentation. You can pass an array there if you need to pass more than a single item, and of course the array can be of any size, and contain nested arrays. The callback will normally get the values that were in the array at the time you use SetCallback(). If that doesn't do what you need, you can put reference variables in the array, and then the callback will get access to the current values when the callback executes. Note PHP object instances are automatically passed as references.

    I'm not sure if this helps, so please follow up with more info if this isn't what you are looking for, or if you want an example.

     
  • Tarskin

    Tarskin - 2012-12-13

    I would love a simple example of how you would define the array to be given to the callback function and how to access this within said function if possible.

    The way i perform the callback currently is (using globals):

    // Calling function
    $plot->SetCallback('draw_all','annotate',$plot);

    // The callback function itself
    function annotate($img, $plot)
    {
    global $mz_array, $int_array, $counter;
    // Retrieve the annotated m/z values from DB
    $query = sprintf("select mz_value.mz, mz_value.composition from glycoPeptide, spectrum, run, precursor, annotation, mz_value where run.glycoPeptide = glycoPeptide.id AND spectrum.run = run.id AND precursor.run = run.id AND spectrum.spectrum like 'm/z' AND mz_value.annotation = annotation.id AND annotation.spectrum = spectrum.id AND precursor.mzValue like '%s' ORDER by glycoPeptide.description, spectrum.spectrum",(string)$_POST['prec']);
    $result = mysql_query($query);
    $i = 0;
    while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
    $anno_mz[$i] = $row[0];
    $anno_comp[$i] = $row[1];
    for ($j = 0; $j < $counter; $j++) {
    $low = $anno_mz[$i] - 0.5;
    $high = $anno_mz[$i] + 0.5;
    if ($mz_array[$j] > $low && $mz_array[$j] < $high && $int_array[$j] > $anno_int[$i]) {
    $anno_int[$i] = $int_array[$j];
    }
    }
    $i++;
    }
    $annotated_masses = $i;
    $text_color = imagecolorresolve($img, 0, 0, 0);
    for ($i = 0; $i < $annotated_masses; $i++) {
    // TODO: Find a way to dynamically check the Y pos for the text
    list($glycan_X,$glycan_Y) = $plot->GetDeviceXY($anno_mz[$i],380000);
    $plot->DrawText('',90,$glycan_X,$glycan_Y,$text_color,$anno_comp[$i],'center','bottom');
    }
    }

    Ideally i would love to pass 2 variables called $mz_array, $int_array and $counter to the callback function which contains all the x/y coordinates of the original dataset that i want to annotate with the result from the second query, thereby elimenating the use of globals.

    Thanks in advance,
    Bas Jansen

     

    Last edit: Tarskin 2012-12-13
  • lbayuk

    lbayuk - 2012-12-13

    Not to side-track the issue, but have you tried using Data Value Labels instead of a drawing annotation callback? With a custom formatting function, you can use whatever text you want for the labels, and let PHPlot put the labels at the data points.

    This is described in the reference manual at Formatting Labels: 'custom' type and Formatting Labels: Extended 'custom' type and there is an Example here.

    Back to your question, you can pass the $plot object plus other data to the callback like this:

    $plot->SetCallback('draw_all', 'annotate',
                       array($plot, $my_data, $my_indexes));
    

    Then your annotate function can split the arguments out like this:

    function annotate($img, $args)
    {
        list($plot, $my_data, $my_indexes) = $args;
        ...
     }
    

    But if annotate() needs to modify my_data or my_indexes, you have to do it with reference variables. (Objects like $plot are always passed by reference.)

    There are other ways, of course, including using an array with string keys, with or without extract().

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.