code: def qq(
      pvals: NumericExpression,
      label: Optional[Union[Expression, Dict[str, Expression]]] = None,
      title: Optional[str] = "Q-Q plot",
      xlabel: Optional[str] = "Expected -log10(p)",
      ylabel: Optional[str] = "Observed -log10(p)",
      size: int = 6,
      legend: bool = True,
      hover_fields: Optional[Dict[str, Expression]] = None,
      colors: Optional[
          Union[ColorMapper, Dict[str, ColorMapper]]
      ] = None,
      width: int = 800,
      height: int = 800,
      collect_all: Optional[bool] = None,
      n_divisions: Optional[int] = 500,
      missing_label: str = "NA",
  ) -> Union[figure, Column]:
      """Create a Quantile-Quantile plot. (https://en.wikipedia.org/wiki/Q-Q_plot)
  
      If no label or a single label is provided, then returns :class:`bokeh.plotting.figure`
      Otherwise returns a :class:`bokeh.models.layouts.Column` containing:
      - a :class:`bokeh.models.widgets.inputs.Select` dropdown selection widget for labels
      - a :class:`bokeh.plotting.figure` containing the interactive qq plot
  
      Points will be colored by one of the labels defined in the ``label`` using the color scheme defined in
      the corresponding entry of ``colors`` if provided (otherwise a default scheme is used). To specify your color
      mapper, check `the bokeh documentation <https://bokeh.pydata.org/en/latest/docs/reference/colors.html>`__
      for CategoricalMapper for categorical labels, and for LinearColorMapper and LogColorMapper
      for continuous labels.
      For categorical labels, clicking on one of the items in the legend will hide/show all points with the corresponding label.
      Note that using many different labelling schemes in the same plots, particularly if those labels contain many
      different classes could slow down the plot interactions.
  
      Hovering on points will display their coordinates, labels and any additional fields specified in ``hover_fields``.
  
      Parameters
      ----------
      pvals : :class:`.NumericExpression`
          List of x-values to be plotted.
      label : :class:`.Expression` or Dict[str, :class:`.Expression`]]
          Either a single expression (if a single label is desired), or a
          dictionary of label name -> label value for x and y values.
          Used to color each point w.r.t its label.
          When multiple labels are given, a dropdown will be displayed with the different options.
          Can be used with categorical or continuous expressions.
      title : str, optional
          Title of the scatterplot.
      xlabel : str, optional
          X-axis label.
      ylabel : str, optional
          Y-axis label.
      size : int
          Size of markers in screen space units.
      legend: bool
          Whether or not to show the legend in the resulting figure.
      hover_fields : Dict[str, :class:`.Expression`], optional
          Extra fields to be displayed when hovering over a point on the plot.
      colors : :class:`bokeh.models.mappers.ColorMapper` or Dict[str, :class:`bokeh.models.mappers.ColorMapper`], optional
          If a single label is used, then this can be a color mapper, if multiple labels are used, then this should
          be a Dict of label name -> color mapper.
          Used to set colors for the labels defined using ``label``.
          If not used at all, or label names not appearing in this dict will be colored using a default color scheme.
      width: int
          Plot width
      height: int
          Plot height
      collect_all : bool
          Deprecated. Use `n_divisions` instead.
      n_divisions : int, optional
          Factor by which to downsample (default value = 500).
          A lower input results in fewer output datapoints.
          Use `None` to collect all points.
      missing_label: str
          Label to use when a point is missing data for a categorical label
  
      Returns
      -------
      :class:`bokeh.plotting.figure` if no label or a single label was given, otherwise :class:`bokeh.models.layouts.Column`
      """
      hover_fields = {} if hover_fields is None else hover_fields
      label_by_col: Dict[str, Expression]
      if label is None:
          label_by_col = {}
      elif isinstance(label, Expression):
          label_by_col = {"label": label}
      else:
          assert isinstance(label, dict)
          label_by_col = label
  
      source = pvals._indices.source
      if isinstance(source, Table):
          ht = source.select(
              p_value=pvals, **hover_fields, **label_by_col
          )
      else:
          assert isinstance(source, MatrixTable)
          ht = source.select_rows(
              p_value=pvals, **hover_fields, **label_by_col
          ).rows()
      ht = (
          ht.key_by()
          .select("p_value", *hover_fields, *label_by_col)
          .key_by("p_value")
      )
      n = ht.aggregate(aggregators.count(), _localize=False)
      ht = ht.annotate(
          observed_p=-hail.log10(ht["p_value"]),
          expected_p=-hail.log10((hail.scan.count() + 1) / n),
      )
      if "p" not in hover_fields:
          hover_fields["p_value"] = ht["p_value"]
      p = scatter(
          ht.expected_p,
          ht.observed_p,
          label={x: ht[x] for x in label_by_col},
          title=title,
          xlabel=xlabel,
          ylabel=ylabel,
          size=size,
          legend=legend,
          hover_fields={x: ht[x] for x in hover_fields},
          colors=colors,
          width=width,
          height=height,
          n_divisions=_downsampling_factor(
              "qq", n_divisions, collect_all
          ),
          missing_label=missing_label,
      )
      from hail.methods.statgen import _lambda_gc_agg
  
      lambda_gc, max_p = ht.aggregate(
          (
              _lambda_gc_agg(ht["p_value"]),
              hail.agg.max(hail.max(ht.observed_p, ht.expected_p)),
          )
      )
      if isinstance(p, Column):
          qq = p.children[1]
      else:
          qq = p
      qq.x_range = DataRange1d(start=0, end=max_p + 1)
      qq.y_range = DataRange1d(start=0, end=max_p + 1)
      qq.add_layout(Slope(gradient=1, y_intercept=0, line_color="red"))
  
      label_color = (
          "red"
          if lambda_gc > 1.25
          else "orange"
          if lambda_gc > 1.1
          else "black"
      )
      lgc_label = Label(
          x=max_p * 0.85,
          y=1,
          text=f"λ GC: {lambda_gc:.2f}",
          text_font_style="bold",
          text_color=label_color,
          text_font_size="14pt",
      )
      p.add_layout(lgc_label)
  
      return p
  
imports: import math
  import collections
  import numpy
  import pandas
  import bokeh
  import bokeh.io
  import bokeh.models
  import warnings
  from bokeh.models import HoverTool, ColorBar, LogTicker, LogColorMapper, LinearColorMapper, CategoricalColorMapper, ColumnDataSource, BasicTicker, Plot, CDSView, GroupFilter, IntersectionFilter, Legend, LegendItem, Renderer, CustomJS, Select, Column, Span, DataRange1d, Slope, Label, ColorMapper, GridPlot
  import bokeh.plotting
  import bokeh.palettes
  from bokeh.plotting import figure
  from bokeh.transform import transform
  from bokeh.layouts import gridplot
  from hail.expr import aggregators
  from hail.expr.expressions import Expression, NumericExpression, StringExpression, LocusExpression, Int32Expression, Int64Expression, Float32Expression, Float64Expression, expr_numeric, expr_float64, expr_any, expr_locus, expr_str, raise_unless_row_indexed
  from hail.expr.functions import _error_from_cdf_python
  from hail.typecheck import typecheck, oneof, nullable, sized_tupleof, numeric, sequenceof, dictof
  from hail import Table, MatrixTable
  from hail.utils.struct import Struct
  from hail.utils.java import warning
  from typing import List, Tuple, Dict, Union, Callable, Optional, Sequence, Any, Set
  import hail
label_desc: Use image node_id 18 for calling a global function with example usage: qq(pvals, label, title, xlabel, ylabel, size, legend, hover_fields, colors, width, height, collect_all, n_divisions, missing_label) and returns: p