swarmplot.m 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. function stackdot_swarm = swarmplot(inputdot,mindist,circdimension,move_bilateral,projection_dir)
  2. % Function for making swarm plots
  3. % Input:
  4. % inputdot: row/column vector or N x 2 matrix. If the input is a
  5. % matrix, it will be projected to the direction defined by the variable
  6. % `projection_dir` and make the swarm plot for that direction
  7. % mindist? scalar, the minimal distance between two points when they
  8. % are not considered as overlapped
  9. % circdimension: boolean (default false), if set to true, make circular swarm plot;
  10. % when input is N x 2 matrix, it will calculate the angle of
  11. % each row vector and make 1D swarm plot but plotted on a
  12. % circle
  13. % move_bilateral: boolean (true), if true, the two overlapped points will be
  14. % move in two direction
  15. % projection_dir: complex scalar (default 1i), complex number whose
  16. % phase angle defined the projection direction.
  17. if ~exist('circdimension','var')
  18. circdimension = [];
  19. end
  20. if ~exist('move_bilateral','var')
  21. move_bilateral = [];
  22. end
  23. if ~exist('projection_dir','var')
  24. projection_dir = [];
  25. end
  26. if isempty(projection_dir)
  27. projection_dir = exp(1i.*pi/2);
  28. else
  29. projection_dir = projection_dir./abs(projection_dir);
  30. end
  31. if isempty(move_bilateral)
  32. move_bilateral = true;
  33. end
  34. if isempty(circdimension)
  35. circdimension = false;
  36. end
  37. if move_bilateral
  38. altersign = -1;
  39. else
  40. altersign = 1;
  41. end
  42. if circdimension
  43. if sum(size(inputdot)>1) == 1
  44. inputdotComplex = 1i.*inputdot(:);
  45. else
  46. inputdotComplex = inputdot(:,1)+1i.*inputdot(:,2);
  47. inputdotComplex = angle(inputdotComplex).*1i;
  48. end
  49. [sortedDot,reverse_order] = sort(imag(inputdotComplex));
  50. [~,reverse_order] = sort(reverse_order);
  51. stackdot_swarm = sortedDot;
  52. else
  53. if sum(size(inputdot)>1) == 1
  54. inputdotComplex = 1i.*inputdot(:);
  55. projection_dir = exp(1i.*pi/2);
  56. else
  57. inputdotComplex = inputdot(:,1)+1i.*inputdot(:,2);
  58. end
  59. [sortedDot,reverse_order] = sort(real(inputdotComplex.*conj(projection_dir)));
  60. [~,reverse_order] = sort(reverse_order);
  61. stackdot_swarm = sortedDot;
  62. end
  63. movesign = 1i;
  64. for i = 2:size(sortedDot,1)
  65. movesign = movesign*altersign;
  66. backtraceidx = find((sortedDot(i) - sortedDot(1:i-1))<mindist,1);
  67. while any(abs(stackdot_swarm(i) - stackdot_swarm(backtraceidx:i-1))<mindist)
  68. stackdot_swarm(i) = stackdot_swarm(i) + mindist*movesign;
  69. end
  70. end
  71. if circdimension
  72. stackdot_swarm = exp(1i.*real(stackdot_swarm)).*(imag(stackdot_swarm)+1);
  73. else
  74. stackdot_swarm = stackdot_swarm.*projection_dir;
  75. end
  76. stackdot_swarm = stackdot_swarm(reverse_order);
  77. end