code: def _make_composite_widget(plots, shape=None, hgap=None, vgap=None):
      if shape is None:
          num_plots = len(plots)
          rows = int(np.floor(np.sqrt(num_plots)))
          cols = int(np.ceil(num_plots / rows))
      else:
          rows, cols = shape
  
      figure = ps.make_subplots(
          rows=rows,
          cols=cols,
          horizontal_spacing=hgap,
          vertical_spacing=vgap,
      )
  
      num_traces = []
      for idx, plot in enumerate(plots):
          r, c = np.unravel_index(idx, (rows, cols))
          row = r + 1
          col = c + 1
          traces = plot._widget.data
          num_traces.append(len(traces))
          for trace in traces:
              figure.add_trace(trace, row=row, col=col)
  
          figure.update_xaxes(
              plot._widget.layout.xaxis, row=row, col=col
          )
          figure.update_yaxes(
              plot._widget.layout.yaxis, row=row, col=col
          )
  
      figure.update_layout(showlegend=False)
  
      return go.FigureWidget(figure)
  
imports: import itertools
  from operator import itemgetter
  import numpy
  import eta.core.utils
  import plotly.subplots
  import plotly.graph_objects
  import fiftyone.core.aggregations
  from .base import ViewPlot
  from .plotly import PlotlyWidgetMixin
label_desc: Use image node_id 1 for calling a global function with example usage: _make_composite_widget(plots, shape, hgap, vgap) and returns: go