figure_max_entropy_rule.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # from scripts.spatial_network.perlin_map.paper_figures_spatial_head_direction_network_perlin_map import FIGURE_SAVE_PATH
  4. FIGURE_SAVE_PATH = '../../../figures/supplement_max_entropy/'
  5. from scripts.spatial_network.perlin_map.run_simulation_perlin_map import get_perlin_map
  6. from scripts.spatial_maps.supplement_max_entropy_rule.spatial_layout import SpatialLayout
  7. from scripts.spatial_maps.spatial_network_layout import Interneuron, get_excitatory_phases_in_inhibitory_axon, get_position_mesh
  8. from scripts.spatial_maps.supplement_max_entropy_rule.spatial_layout import get_entropy
  9. def plot_neural_sheet(ex_positions, ex_tunings, axonal_clouds=None):
  10. X, Y = get_position_mesh(ex_positions)
  11. n_ex = int(np.sqrt(len(ex_positions)))
  12. head_dir_preference = np.array(ex_tunings).reshape((n_ex, n_ex))
  13. fig = plt.figure(figsize=(4, 4))
  14. ax = fig.add_subplot(111)
  15. c = ax.pcolor(X, Y, head_dir_preference, vmin=-np.pi, vmax=np.pi, cmap="twilight")
  16. fig.colorbar(c, ax=ax, label="Orientation")
  17. if axonal_clouds is not None:
  18. for i, p in enumerate(axonal_clouds):
  19. ell = p.get_ellipse()
  20. # print(ell)
  21. ax.add_artist(ell)
  22. # Get input map
  23. seed = 1
  24. correlation_length = 200
  25. map_size = 900
  26. long_half = 100
  27. short_half = 25
  28. Ne = 3600
  29. Ni = 400
  30. Ne_per_row = int(np.sqrt(Ne))
  31. Ni_per_row = int(np.sqrt(Ni))
  32. input_map = get_perlin_map(correlation_length, seed, map_size, Ne)
  33. spatial_layout = SpatialLayout(input_map, Ne, Ni, long_half, short_half, map_size)
  34. plot_neural_sheet(spatial_layout.ex_positions, spatial_layout.ex_tunings)
  35. # Choose interneuron and get entropies
  36. in_idx = 144
  37. pos_x = spatial_layout.in_positions[in_idx][0]
  38. pos_y = spatial_layout.in_positions[in_idx][1]
  39. equivalent_radius = np.sqrt(long_half * short_half)
  40. circular_axon = Interneuron(pos_x, pos_y, equivalent_radius, equivalent_radius, 0)
  41. neuron_positions = spatial_layout.ex_positions
  42. neuron_tunings = spatial_layout.ex_tunings
  43. number_of_phases = 36
  44. phases = np.linspace(-np.pi / 2, np.pi / 2, number_of_phases, endpoint=False)
  45. number_of_bins = 10
  46. tuning_bins = np.linspace(-np.pi, np.pi, number_of_bins + 1)
  47. tunings = []
  48. entropies = []
  49. for phase in phases:
  50. axonal_cloud = Interneuron(pos_x, pos_y, long_half, short_half, phase)
  51. tunings.append(get_excitatory_phases_in_inhibitory_axon(neuron_positions, neuron_tunings, axonal_cloud))
  52. entropies.append(get_entropy(axonal_cloud, neuron_positions, neuron_tunings, tuning_bins))
  53. circular_entropy = get_entropy(circular_axon, neuron_positions, neuron_tunings, tuning_bins)
  54. max_entropy = max(entropies)
  55. max_phase = phases[np.argmax(entropies)]
  56. max_id = np.argmax(entropies)
  57. min_entropy = min(entropies)
  58. min_phase = phases[np.argmin(entropies)]
  59. min_id = np.argmin(entropies)
  60. circular_tuning = get_excitatory_phases_in_inhibitory_axon(neuron_positions, neuron_tunings, circular_axon)
  61. # Figures
  62. import matplotlib
  63. # In[20]:
  64. plt.style.use('../../model_figure/figures.mplstyle')
  65. # In[21]:
  66. width = 4.0 / 2.54
  67. height = 3.2 / 2.54
  68. detail_size = 2.5 * long_half
  69. detail_x_low = pos_x - detail_size / 2.0
  70. detail_x_high = pos_x + detail_size / 2.0
  71. detail_y_low = pos_y - detail_size / 2.0
  72. detail_y_high = pos_y + detail_size / 2.0
  73. colormap = matplotlib.cm.get_cmap('hsv')
  74. bar_colors = [colormap(value) for value in np.linspace(0, 1, number_of_bins)]
  75. X, Y = get_position_mesh(spatial_layout.ex_positions)
  76. head_dir_preference = np.array(spatial_layout.ex_tunings).reshape((Ne_per_row, Ne_per_row))
  77. # ### Polar Interneuron
  78. # In[22]:
  79. fig = plt.figure(figsize=(width, height))
  80. ax_map = fig.add_axes([0.05, 0.1, 0.7 * height / width, 0.7])
  81. ax_map.pcolor(X, Y, head_dir_preference, vmin=-np.pi, vmax=np.pi, cmap=colormap)
  82. line_length = 1.2 * detail_size
  83. max_entropy_ell = Interneuron(pos_x, pos_y, long_half, short_half, max_phase).get_ellipse()
  84. max_entropy_line = plt.Line2D(
  85. [pos_x - np.cos(max_phase) * line_length / 2.0, pos_x + np.cos(max_phase) * line_length / 2.0],
  86. [pos_y - np.sin(max_phase) * line_length / 2.0, pos_y + np.sin(max_phase) * line_length / 2.0])
  87. max_entropy_line.set_linestyle('dotted')
  88. max_entropy_line.set_clip_on(False)
  89. min_entropy_ell = Interneuron(pos_x, pos_y, long_half, short_half, min_phase).get_ellipse()
  90. min_entropy_ell.set_linestyle('dashed')
  91. min_entropy_line = plt.Line2D(
  92. [pos_x - np.cos(min_phase) * line_length / 2.0, pos_x + np.cos(min_phase) * line_length / 2.0],
  93. [pos_y - np.sin(min_phase) * line_length / 2.0, pos_y + np.sin(min_phase) * line_length / 2.0])
  94. min_entropy_line.set_linestyle('dotted')
  95. min_entropy_line.set_clip_on(False)
  96. ax_map.add_artist(max_entropy_ell)
  97. ax_map.add_artist(max_entropy_line)
  98. ax_map.add_artist(min_entropy_ell)
  99. ax_map.add_artist(min_entropy_line)
  100. ax_map.set_xlim(detail_x_low, detail_x_high)
  101. ax_map.set_ylim(detail_y_low, detail_y_high)
  102. ax_map.spines["right"].set_visible(False)
  103. ax_map.spines["left"].set_visible(False)
  104. ax_map.spines["top"].set_visible(False)
  105. ax_map.spines["bottom"].set_visible(False)
  106. ax_map.xaxis.set_ticks([])
  107. ax_map.yaxis.set_ticks([])
  108. ax_map.text(pos_x - np.cos(max_phase) * line_length / 2.0, pos_y - np.sin(max_phase) * line_length / 2.0,
  109. "$\\phi_{max}$", va='bottom', ha='left')
  110. ax_map.text(pos_x + np.cos(min_phase) * line_length / 2.0, pos_y + np.sin(min_phase) * line_length / 2.0,
  111. "$\\phi_{min}$", va='center', ha='left')
  112. ax_dist_max = fig.add_axes(
  113. [0.05 + 0.7 * height / width + 0.03, 0.1, 1 - 0.75 * height / width - 0.05 - 0.05 - 0.1, 0.27])
  114. n_max_entropy, _, bars = ax_dist_max.hist(tunings[max_id], bins=number_of_bins, range=(-np.pi, np.pi))
  115. for bar, bar_color in zip(bars, bar_colors):
  116. bar.set_color(bar_color)
  117. ax_dist_max.text(0, 1.4, "$\\phi_{max}$\n" + "S={:.2f}".format(entropies[max_id]), transform=ax_dist_max.transAxes,
  118. va='top')
  119. ax_dist_min = fig.add_axes(
  120. [0.05 + 0.7 * height / width + 0.03, 0.48, 1 - 0.75 * height / width - 0.05 - 0.05 - 0.1, 0.27])
  121. n_min_entropy, _, bars = ax_dist_min.hist(tunings[min_id], bins=number_of_bins, range=(-np.pi, np.pi))
  122. for bar, bar_color in zip(bars, bar_colors):
  123. bar.set_color(bar_color)
  124. ax_dist_min.text(0, 1.6, "$\\phi_{min}$\n" + "S={:.2f}".format(entropies[min_id]), transform=ax_dist_min.transAxes,
  125. va='top')
  126. for ax in [ax_dist_max, ax_dist_min]:
  127. ax.set_ylim(0, max(max(n_max_entropy), max(n_min_entropy)))
  128. ax.spines["right"].set_visible(False)
  129. ax.spines["left"].set_visible(False)
  130. ax.spines["top"].set_visible(False)
  131. ax.spines["bottom"].set_linewidth(0.5)
  132. ax.xaxis.set_ticks([])
  133. ax.yaxis.tick_right()
  134. fig.savefig(FIGURE_SAVE_PATH + "B_ii_max_entropy_rule_polar_ins.png")
  135. # ### Circular Interneuron
  136. # In[25]:
  137. from scripts.model_figure.figure_utils import add_length_scale
  138. # In[36]:
  139. fig = plt.figure(figsize=(width, height))
  140. ax_map = fig.add_axes([0.05, 0.1, 0.7 * height / width, 0.7])
  141. ax_map.pcolor(X, Y, head_dir_preference, vmin=-np.pi, vmax=np.pi, cmap=colormap)
  142. circle = Interneuron(pos_x, pos_y, equivalent_radius, equivalent_radius, 0).get_ellipse()
  143. ax_map.add_artist(circle)
  144. ax_map.set_xlim(detail_x_low, detail_x_high)
  145. ax_map.set_ylim(detail_y_low, detail_y_high)
  146. ax_map.spines["right"].set_visible(False)
  147. ax_map.spines["left"].set_visible(False)
  148. ax_map.spines["top"].set_visible(False)
  149. ax_map.spines["bottom"].set_visible(False)
  150. ax_map.xaxis.set_ticks([])
  151. ax_map.yaxis.set_ticks([])
  152. add_length_scale(ax_map, 100, detail_x_high + 30, detail_x_high + 10 + 100, detail_y_low + 40, detail_y_low + 40)
  153. ax_dist = fig.add_axes([0.05 + 0.7 * height / width + 0.03, 0.375, 1 - 0.75 * height / width - 0.05 - 0.05 - 0.1, 0.27])
  154. n_circle, _, bars = ax_dist.hist(circular_tuning, bins=number_of_bins, range=(-np.pi, np.pi))
  155. for bar, bar_color in zip(bars, bar_colors):
  156. bar.set_color(bar_color)
  157. ax_dist.text(0, 1.6, "circ. \nS={:.2f}".format(circular_entropy), transform=ax_dist.transAxes, va='top')
  158. for ax in [ax_dist]:
  159. ax.set_ylim(0, max(max(n_max_entropy), max(n_min_entropy)))
  160. ax.spines["right"].set_visible(False)
  161. ax.spines["left"].set_visible(False)
  162. ax.spines["top"].set_visible(False)
  163. ax.spines["bottom"].set_linewidth(0.5)
  164. ax.xaxis.set_ticks([])
  165. ax.yaxis.tick_right()
  166. fig.savefig(FIGURE_SAVE_PATH + "B_ii_max_entropy_rule_circular_in.png")