bokeh_util.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from __future__ import annotations
  2. from typing import TYPE_CHECKING, cast
  3. from contourpy import FillType, LineType
  4. from contourpy.util.mpl_util import mpl_codes_to_offsets
  5. if TYPE_CHECKING:
  6. from contourpy._contourpy import (
  7. CoordinateArray, FillReturn, LineReturn, LineReturn_Separate, LineReturn_SeparateCode,
  8. )
  9. def filled_to_bokeh(
  10. filled: FillReturn,
  11. fill_type: FillType,
  12. ) -> tuple[list[list[CoordinateArray]], list[list[CoordinateArray]]]:
  13. xs: list[list[CoordinateArray]] = []
  14. ys: list[list[CoordinateArray]] = []
  15. if fill_type in (FillType.OuterOffset, FillType.ChunkCombinedOffset,
  16. FillType.OuterCode, FillType.ChunkCombinedCode):
  17. have_codes = fill_type in (FillType.OuterCode, FillType.ChunkCombinedCode)
  18. for points, offsets in zip(*filled):
  19. if points is None:
  20. continue
  21. if have_codes:
  22. offsets = mpl_codes_to_offsets(offsets)
  23. xs.append([]) # New outer with zero or more holes.
  24. ys.append([])
  25. for i in range(len(offsets)-1):
  26. xys = points[offsets[i]:offsets[i+1]]
  27. xs[-1].append(xys[:, 0])
  28. ys[-1].append(xys[:, 1])
  29. elif fill_type in (FillType.ChunkCombinedCodeOffset, FillType.ChunkCombinedOffsetOffset):
  30. for points, codes_or_offsets, outer_offsets in zip(*filled):
  31. if points is None:
  32. continue
  33. for j in range(len(outer_offsets)-1):
  34. if fill_type == FillType.ChunkCombinedCodeOffset:
  35. codes = codes_or_offsets[outer_offsets[j]:outer_offsets[j+1]]
  36. offsets = mpl_codes_to_offsets(codes) + outer_offsets[j]
  37. else:
  38. offsets = codes_or_offsets[outer_offsets[j]:outer_offsets[j+1]+1]
  39. xs.append([]) # New outer with zero or more holes.
  40. ys.append([])
  41. for k in range(len(offsets)-1):
  42. xys = points[offsets[k]:offsets[k+1]]
  43. xs[-1].append(xys[:, 0])
  44. ys[-1].append(xys[:, 1])
  45. else:
  46. raise RuntimeError(f"Conversion of FillType {fill_type} to Bokeh is not implemented")
  47. return xs, ys
  48. def lines_to_bokeh(
  49. lines: LineReturn,
  50. line_type: LineType,
  51. ) -> tuple[list[CoordinateArray], list[CoordinateArray]]:
  52. xs: list[CoordinateArray] = []
  53. ys: list[CoordinateArray] = []
  54. if line_type == LineType.Separate:
  55. if TYPE_CHECKING:
  56. lines = cast(LineReturn_Separate, lines)
  57. for line in lines:
  58. xs.append(line[:, 0])
  59. ys.append(line[:, 1])
  60. elif line_type == LineType.SeparateCode:
  61. if TYPE_CHECKING:
  62. lines = cast(LineReturn_SeparateCode, lines)
  63. for line in lines[0]:
  64. xs.append(line[:, 0])
  65. ys.append(line[:, 1])
  66. elif line_type in (LineType.ChunkCombinedCode, LineType.ChunkCombinedOffset):
  67. for points, offsets in zip(*lines):
  68. if points is None:
  69. continue
  70. if line_type == LineType.ChunkCombinedCode:
  71. offsets = mpl_codes_to_offsets(offsets)
  72. for i in range(len(offsets)-1):
  73. line = points[offsets[i]:offsets[i+1]]
  74. xs.append(line[:, 0])
  75. ys.append(line[:, 1])
  76. else:
  77. raise RuntimeError(f"Conversion of LineType {line_type} to Bokeh is not implemented")
  78. return xs, ys