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
Retrieve X/Y dataset from DB
callback function definition (retrieves X/label dataset from DB, currently places label at a predetermined height)
Plot X/Y data as thin bar plot
perform callback function
drawgraph
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.
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
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:
Then your annotate function can split the arguments out like this:
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().