nodes: 0, module; 1, function_definition; 2, function_name:_get_coords; 3, parameters; 4, block; 5, identifier:self; 6, identifier:obj; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, comment:# Determine global orderings of y-values using topological sort; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, for_statement; 16, if_statement; 17, return_statement; 18, comment:"""
          Get the coordinates of the 2D aggregate, maintaining the correct
          sorting order.
          """; 19, assignment; 20, assignment; 21, assignment; 22, assignment; 23, assignment; 24, assignment; 25, identifier:group; 26, identifier:grouped; 27, block; 28, boolean_operator; 29, block; 30, elif_clause; 31, expression_list; 32, pattern_list; 33, subscript; 34, identifier:xcoords; 35, call; 36, identifier:ycoords; 37, call; 38, identifier:grouped; 39, call; 40, identifier:orderings; 41, call; 42, identifier:sort; 43, True; 44, expression_statement; 45, if_statement; 46, if_statement; 47, identifier:sort; 48, call; 49, expression_statement; 50, not_operator; 51, block; 52, identifier:xcoords; 53, identifier:ycoords; 54, identifier:xdim; 55, identifier:ydim; 56, call; 57, slice; 58, attribute; 59, argument_list; 60, attribute; 61, argument_list; 62, attribute; 63, argument_list; 64, identifier:OrderedDict; 65, argument_list; 66, assignment; 67, comparison_operator:len(vals) == 1; 68, block; 69, else_clause; 70, identifier:sort; 71, block; 72, identifier:one_to_one; 73, argument_list; 74, assignment; 75, call; 76, expression_statement; 77, expression_statement; 78, attribute; 79, argument_list; 80, integer:2; 81, identifier:obj; 82, identifier:dimension_values; 83, identifier:xdim; 84, False; 85, identifier:obj; 86, identifier:dimension_values; 87, identifier:ydim; 88, False; 89, call; 90, identifier:values; 91, identifier:vals; 92, call; 93, call; 94, integer:1; 95, expression_statement; 96, block; 97, if_statement; 98, identifier:orderings; 99, identifier:ycoords; 100, identifier:ycoords; 101, call; 102, identifier:is_cyclic; 103, argument_list; 104, assignment; 105, assignment; 106, identifier:obj; 107, identifier:dimensions; 108, keyword_argument; 109, attribute; 110, argument_list; 111, attribute; 112, argument_list; 113, identifier:len; 114, argument_list; 115, assignment; 116, for_statement; 117, comparison_operator:vals.dtype.kind in ('i', 'f'); 118, block; 119, else_clause; 120, attribute; 121, argument_list; 122, identifier:orderings; 123, identifier:coords; 124, call; 125, identifier:ycoords; 126, conditional_expression:coords if len(coords) == len(ycoords) else np.sort(ycoords); 127, identifier:label; 128, True; 129, identifier:obj; 130, identifier:groupby; 131, identifier:xdim; 132, keyword_argument; 133, keyword_argument; 134, identifier:group; 135, identifier:dimension_values; 136, identifier:ydim; 137, False; 138, identifier:vals; 139, subscript; 140, list; 141, identifier:i; 142, call; 143, block; 144, attribute; 145, tuple; 146, expression_statement; 147, block; 148, identifier:np; 149, identifier:sort; 150, identifier:ycoords; 151, identifier:list; 152, argument_list; 153, identifier:coords; 154, comparison_operator:len(coords) == len(ycoords); 155, call; 156, identifier:container_type; 157, identifier:OrderedDict; 158, identifier:group_type; 159, identifier:Dataset; 160, identifier:orderings; 161, subscript; 162, subscript; 163, identifier:range; 164, argument_list; 165, expression_statement; 166, expression_statement; 167, attribute; 168, identifier:kind; 169, string; 170, string; 171, assignment; 172, expression_statement; 173, call; 174, call; 175, call; 176, attribute; 177, argument_list; 178, identifier:vals; 179, integer:0; 180, identifier:vals; 181, integer:0; 182, binary_operator:len(vals)-1; 183, assignment; 184, assignment; 185, identifier:vals; 186, identifier:dtype; 187, string_content:i; 188, string_content:f; 189, identifier:sort; 190, call; 191, assignment; 192, attribute; 193, argument_list; 194, identifier:len; 195, argument_list; 196, identifier:len; 197, argument_list; 198, identifier:np; 199, identifier:sort; 200, identifier:ycoords; 201, call; 202, integer:1; 203, pattern_list; 204, subscript; 205, subscript; 206, list; 207, attribute; 208, argument_list; 209, identifier:sort; 210, call; 211, identifier:itertools; 212, identifier:chain; 213, list_splat; 214, identifier:coords; 215, identifier:ycoords; 216, identifier:len; 217, argument_list; 218, identifier:p1; 219, identifier:p2; 220, identifier:vals; 221, slice; 222, identifier:orderings; 223, identifier:p1; 224, identifier:p2; 225, parenthesized_expression; 226, identifier:all; 227, attribute; 228, argument_list; 229, call; 230, identifier:vals; 231, identifier:i; 232, binary_operator:i+2; 233, comparison_operator:np.diff(vals)>=0; 234, identifier:np; 235, identifier:array_equal; 236, call; 237, identifier:vals; 238, identifier:sort_topologically; 239, argument_list; 240, identifier:i; 241, integer:2; 242, call; 243, integer:0; 244, attribute; 245, argument_list; 246, identifier:orderings; 247, attribute; 248, argument_list; 249, identifier:np; 250, identifier:sort; 251, identifier:vals; 252, identifier:np; 253, identifier:diff; 254, identifier:vals
code: def _get_coords(self, obj):
          """
          Get the coordinates of the 2D aggregate, maintaining the correct
          sorting order.
          """
          xdim, ydim = obj.dimensions(label=True)[:2]
          xcoords = obj.dimension_values(xdim, False)
          ycoords = obj.dimension_values(ydim, False)
  
          # Determine global orderings of y-values using topological sort
          grouped = obj.groupby(xdim, container_type=OrderedDict,
                                group_type=Dataset).values()
          orderings = OrderedDict()
          sort = True
          for group in grouped:
              vals = group.dimension_values(ydim, False)
              if len(vals) == 1:
                  orderings[vals[0]] = [vals[0]]
              else:
                  for i in range(len(vals)-1):
                      p1, p2 = vals[i:i+2]
                      orderings[p1] = [p2]
              if sort:
                  if vals.dtype.kind in ('i', 'f'):
                      sort = (np.diff(vals)>=0).all()
                  else:
                      sort = np.array_equal(np.sort(vals), vals)
          if sort or one_to_one(orderings, ycoords):
              ycoords = np.sort(ycoords)
          elif not is_cyclic(orderings):
              coords = list(itertools.chain(*sort_topologically(orderings)))
              ycoords = coords if len(coords) == len(ycoords) else np.sort(ycoords)
          return xcoords, ycoords