docs: def get_result_figure(
          result, show_title=False, title=None, show_inset=True,
          plot_fold_enrichment=False,
          width=800, height=350, font_size=24, margin=None,
          font_family='Computer Modern Roman, serif',
          score_color='rgb(0,109,219)',
          enrichment_color='rgb(219,109,0)',
          cutoff_color='rgba(255, 52, 52, 0.7)',
          line_width=2.0,
          ymax=None,
          mHG_label=False):
      """Visualize an XL-mHG test result.
  
      Parameters
      ----------
      result : `mHGResult`
          The test result.
      show_title : bool, optional
          Whether to include a title in the figure. If `title` is not
          ``None``, this parameter is ignored. [False]
      title : str or None, optional
          Figure title. If not ``None``, `show_title` is ignored. [None]
      show_inset : bool, optional
          Whether to show test parameters and p-value as an inset. [True]
      plot_fold_enrichment : bool, optional
          Whether to plot the fold enrichment on a second axis. [False]
      width : int, optional
          The width of the figure (in pixels). [800]
      height : int, optional
          The height of the figure (in pixels). [350]
      font_size : int, optional
          The font size to use. [20]
      margin : dict, optional
          A dictionary specifying the figure margins (in pixels).
          Valid keys are "l" (left), "r" (right), "t" (top), and "b" (bottom).
          Missing keys are replaced by Plotly default values. If ``None``, will
          be set to a dictionary specifying a left margin of 100 px, and a top
          margin of 40 px. [None]
      font_family : str, optional
          The font family (name) to use. ["Computer Modern Roman, serif"]
      score_color : str, optional
          The color used for plotting the enrichment scores. ["rgb(0,109,219)"]
      enrichment_color : str, optional
          The color used for plotting the fold enrichment values (if enabled).
          ["rgb(219,109,0)"]
      cutoff_color : str, optional
          The color used for indicating the XL-mHG test cutoff.
          ["rgba(255, 109,182,0.5)"]
      line_width : int or float, optional
          The line width used for plotting. [2.0]
      ymax : int or float or None, optional
          The y-axis limit. If ``None``, determined automatically. [None]
      mHG_label : bool, optional
          If ``True``, label the p-value with "mHG" instead of "XL-mHG". [False]
  
      Returns
      -------
      `plotly.graph_obs.Figure`
          The Plotly figure.
      """
  
      assert isinstance(result, mHGResult)
      assert isinstance(show_title, bool)
      if title is not None:
          assert isinstance(title, (str, _oldstr))
      assert isinstance(show_inset, bool)
      assert isinstance(plot_fold_enrichment, bool)
      assert isinstance(font_family, (str, _oldstr))
      assert isinstance(width, int)
      assert isinstance(height, int)
      assert isinstance(font_size, (int, float))
      if margin is not None:
          assert isinstance(margin, dict)
      assert isinstance(score_color, (str, _oldstr))
      assert isinstance(enrichment_color, (str, _oldstr))
      assert isinstance(line_width, (int, float))
      if ymax is not None:
          assert isinstance(ymax, (int, float))
      assert isinstance(mHG_label, bool)
  
      pvals, folds = get_hypergeometric_stats(result.N, result.indices)
      pval_max = max(int(ceil(-np.log10(np.amin(pvals)))), 1.0)
  
      if ymax is not None:
          pval_max = ymax
  
      pval_min = 0.0
      X = result.X
      L = result.L
      N = result.N
      K = result.K
      fold_start = result.indices[0] + 1
  
      data = []
  
      # generate p-value trace
      data.append(go.Scatter(
          x=np.arange(N+1),
          y=-np.log10(pvals),
          mode='line',
          line=dict(
              color=score_color,
              width=line_width,
          ),
          name='Enrichment score'
      ))
  
      # generate p-value axis
      tick_color = None
      if plot_fold_enrichment:
          tick_color = score_color
      yaxis = go.YAxis(
          #title='-log<sub>10</sub>(hypergeom. p-value)',
          title='Enrichment score',
          tickfont=dict(
              color=tick_color,
          ),
          autorange=False,
          #range=[pval_min, pval_max],
          range=[pval_min, pval_max],
          showgrid=False,
          #zeroline=False,
          zeroline=False,
          showline=True,
          domain=[0.15, 1.0],
          #mirror=True,
      )
  
      # additional y axis at the the bottom,
      # showing the occurrences of the "1's"
      yaxis3 = go.YAxis(
          domain=[0, 0.1],
          anchor='x',
          mirror=True,
          zeroline=False,
          showline=False,
          showgrid=False,
          autorange=False,
          range=[0, 1],
          ticks='',
          showticklabels=False,
      )
  
      # format p-value string
      pval_str = '%.1e' % (result.pval)
      e_idx = pval_str.index('e')
      exponent = int(pval_str[(e_idx + 1):])
      pval_str = pval_str[:e_idx] + '*10<sup>%d</sup>' % exponent
  
      # fe_str = '%.1fx' % (result.fold_enrichment)
  
      # if show_title:
      if show_title and title is None:
          title = 'XL-mHG test result (N=%d, K=%d)' % (N, K)
  
      # specify margins (if not provided)
      if margin is None:
          t = 42
          if title is None:
              t = 22
          margin = dict(
              l=70,
              t=t,
              b=60,
          )
  
      if plot_fold_enrichment:
          fold_min_int = -0.3
          if np.log2(np.amin(folds[fold_start:])) < -0.3:
              fold_min_int = int(floor(np.log2(np.amin(folds[fold_start:]))))
          fold_max_int = max(int(ceil(np.log2(np.amax(folds)))), 2)
  
          # generate fold enrichment trace
          data.append(go.Scatter(
              x=np.arange(fold_start, result.N + 1),
              y=np.log2(folds[fold_start:]),
              yaxis='y2',
              mode='line',
              line=dict(
                  color=enrichment_color,
                  width=line_width
              ),
          ))
  
          # generate fold enrichment axis
          yaxis2 = go.YAxis(
              title='log<sub>2</sub>(Fold enrichment)',
              # titlefont=dict(
              #    color='rgb(148, 103, 189)'
              # ),
              tickfont=dict(
                  color=enrichment_color,
              ),
              range=[fold_min_int, fold_max_int],
              overlaying='y',
              side='right',
              showgrid=False,
              zeroline=False,
              showline=True,
          )
  
      font = dict(
          size=font_size,
          family=font_family,
      )
  
      # rectangles showing which ranks are excluded
      # in the calculation of the test statistic
      # (due to X and L parameters)
      rect_col = 'rgba(60,60,60,0.10)'
  
      rect1_x1 = 0
      if result.X > 0:
          if result.X < result.K:
              rect1_x1 = result.indices[result.X-1] + 0.5
          else:
              rect1_x1 = result.N
      rect1 = {
          'type': 'rect',
          'x0': 0,
          'y0': pval_min,
          'x1': rect1_x1,
          'y1': pval_max,
          'line': dict(
              width=0,
          ),
          'fillcolor': rect_col,
      }
      rect2 = {
          'type': 'rect',
          'x0': L+0.5,
          'y0': pval_min,
          'x1': N,
          'y1': pval_max,
          'line': dict(
              width=0,
          ),
          'fillcolor': rect_col,
      }
  
      # bars in second Y axis symbolizing the occurrences of the "1's"
      bars = []
      for n in result.indices:
          bars.append(dict(
              type='line',
              x0=n+1.0,
              y0=0.0,
              x1=n+1.0,
              y1=1.0,
              line=dict(
                  color='black',
                  width=line_width,
              ),
              yref='y3',
              opacity=0.7,
          ))
  
      if not mHG_label:
          # show XL-mHG p-value
          pval_text = ('<b><i>p</i><sup>XL-mHG</sup> = '
                       '%s</b><br>(X=%d, L=%d; %d/%d @ %d)') \
                      % (pval_str, result.X, result.L,
                         result.k, result.K, result.cutoff)
      else:
          # show mHG p-value
          pval_text = ('<b><i>p</i><sup>mHG</sup> = '
                       '%s</b><br>(%d/%d @ %d)') \
                      % (pval_str,
                         result.k, result.K, result.cutoff)
  
      annotations = []
      if show_inset:
          annotations.append(
              go.Annotation(
                  x=0.98,
                  y=0.96,
                  align='right',
                  showarrow=False,
                  text=pval_text,
                  xref='paper',
                  yref='paper',
                  xanchor='right',
                  yanchor='top',
                  font=font,
              ),
          )
  
      line = {
          'type': 'line',
          'x0': result.cutoff,
          'y0': pval_min,
          'x1': result.cutoff,
          'y1': pval_max,
          'line': dict(
              color=cutoff_color,
              width=1.5*line_width,
              dash='dash',
          ),
      }
  
      line2 = {
          'type': 'line',
          'x0': 0,
          'y0': 0,
          'x1': result.N,
          'y1': 0,
          'line': dict(
              color='black',
              width=1.0,
          ),
      }
  
      layout = go.Layout(
          width=width,
          height=height,
          margin=margin,
          xaxis=dict(
              title='Rank cutoff',
              zeroline=False,
              range=[1.0, result.N],
              showline=True,
              anchor='y3',
          ),
          yaxis=yaxis,
          yaxis3=yaxis3,
          titlefont=dict(
              size=font_size,
              family=font_family,
          ),
          font=dict(
              size=font_size,
              family=font_family,
          ),
          showlegend=False,
          shapes=[
              rect1,
              rect2,
              line,
              line2,
          ] + bars,
          title=title,
          annotations=annotations,
      )
  
      if plot_fold_enrichment:
          layout.yaxis2 = yaxis2
  
      fig = go.Figure(
          data=data,
          layout=layout,
      )
  
      return fig