function plot_function ($function, $variable, $range_start, $range_end, $width, $height, $pixels_per_plot, $color, $show_grid
{
  // fix the pixels/plot variable
  $pixels_per_plot = floor$pixels_per_plot);
  if ($pixels_per_plot<=0) $pixels_per_plot = 1;
 Â
  // calculate all our points
  $xy = array();
  for ($ii=0; $ii<($width$pixels_per_plot); $ii$ii$pixels_per_plot) {
    if ($ii>=$width) {
      $x = $range_start + ($range_end - $range_start);
    } else {
      $x = $range_start + $ii$width * ($range_end - $range_start);
    }
    $y = evaluate_for_x$function, $x);
    if (!is_nan$y)) {
      $xy[]=array$x$y);
    }
  }
 Â
  // find the min and max values of x
  for ($ii=0; $iicount$xy); $ii++) {
    if (is_finite$xy$ii][1])) {
      if ((isset$miny)) && (isset$maxy)))  {
        if ($xy$ii][1]<$miny) $miny = $xy$ii][1];
        if ($xy$ii][1]>$maxy) $maxy = $xy$ii][1];
      } else {
        $maxy = $xy$ii][1];
        $miny = $xy$ii][1];
      }
    }
  }
  if (!isset$maxy)) $maxy = 1;
  if (!isset$miny)) $miny = -1;
 Â
  // if height is not given, compute it automatically
  if ($height<=0) {
    $height = ceil(($maxy$miny)/($range_end$range_start)*$width);
    if ($height>2000) $height = 2000;
  }
 Â
  // create blank image
  $image = image_create_alpha$width, $height+1);
 Â
  // create the colors
  $r  = hexdecsubstr$color, 0, 2));
  $g  = hexdecsubstr$color, 2, 2));
  $b  = hexdecsubstr$color, 4, 2));
  $color = imagecolorallocate$image, $r, $g, $b);
 Â
  // determine the view port for the y axis (where on the y axis should we focus?)
  $bottom_y = ($maxy$miny)/2 - (($height$width)*($range_end$range_start)/2);
  $top_y = $bottom_y + (($height$width)*($range_end$range_start));
 Â
  // numbers to shift by so that the graph is focused on the right spot
  $shift_y = $bottom_y*-1;
  $shift_x = $range_start*-1;
  // factor to translate the plotted points to pixel locations
  $mult = $width/($range_end$range_start);
 Â
  // draw the graph lines
  if ($show_grid) {
    $graph_color = imagecolorallocate$image, 200, 200, 200);
    $minor_color = imagecolorallocate$image, 230, 230, 230);
 Â
    $line_every = 50/$mult; // lines approximately every 50 pixels
    $places = floorlog$line_every,10))*-1;
    $line_every = round$line_every/5, $places)*5; // try and make the graph lines appear at a nice divisible by 5 number
    if ($line_every==0) $line_every=1; // this shouldn't happen, but just in case don't want to divide by 0
   Â
    // vertical lines
    $vert_line = floor$range_start$line_every) * $line_every
    while ($vert_line<=$range_end) {
      imageline$image, round(($vert_line$shift_x)*$mult), 0, round(($vert_line$shift_x)*$mult), $height, $minor_color);
      imagestring$image, 1, round(($vert_line$shift_x)*$mult)+1, $height-10, "$vert_line", $graph_color);
      $vert_line = $vert_line$line_every
    }
 Â
    // horizontal lines
    $horiz_line = floor$bottom_y$line_every) * $line_every
    while ($horiz_line<=$top_y) {
      imageline$image, 0, $heightround(($horiz_line$shift_y)*$mult), $width, $heightround(($horiz_line$shift_y)*$mult), $minor_color);
      imagestring$image, 1, 5, $heightround(($horiz_line$shift_y)*$mult), "$horiz_line", $graph_color);
      $horiz_line = $horiz_line$line_every
    }
   Â
    // axis lines
    imageline$image, round$shift_x$mult), 0, round$shift_x$mult), $height, $graph_color);
    imageline$image, 0, $heightround$shift_y$mult), $width, $heightround$shift_y$mult), $graph_color);
  }
 Â
  // draw the line
  for ($ii=0; $iicount$xy)-1; $ii++) {
   Â
    // infinite number?
    if (is_infinite$xy$ii][1])) {
      if ($xy$ii][1]<0) $xy$ii][1]=$bottom_y-100000;
      else $xy$ii][1]=$top_y+100000;
    }
   Â
    // translate the plotted values to locations in the image
    $x1 = round(($xy$ii][0]+$shift_x)*$mult);
    $y1 = $heightround(($xy$ii][1]+$shift_y)*$mult);
    $x2 = round(($xy$ii+1][0]+$shift_x)*$mult);
    $y2 = $heightround(($xy$ii+1][1]+$shift_y)*$mult);
   Â
    // draw the line
    imageline$image, $x1, $y1, $x2, $y2, $color);
  }
 Â
  return $image
}Â