Advertisement
Guest User

Vote Simulation

a guest
Jul 16th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.50 KB | None | 0 0
  1. import matplotlib.pyplot as plt
  2. import pandas as pd
  3. import numpy as np
  4. import matplotlib.image as mpimg
  5. from matplotlib.text import TextPath
  6. from mpl_toolkits.mplot3d import Axes3D
  7. from matplotlib import cm
  8. #
  9. # Types of problems to handle
  10. # https://www.rangevoting.org/AssetBC.html
  11. # https://groups.google.com/forum/#!topic/electionscience/Rk4ZGf-s-s8
  12.  
  13. centerists = False
  14. #centerists = True
  15. #maximize = False
  16. maximize = True
  17.  
  18. #Number of winners
  19. W = 3
  20.  
  21. #the maximum possible score is 5
  22. K = 5.0
  23.  
  24. voter_groups = []
  25.  
  26. #Three parties
  27. # mean_red = [-2.5*np.sqrt(3), 2.5]
  28. # cov_red = [[5, 0], [0, 5]]  # diagonal covariance
  29. # pos_red = np.random.multivariate_normal(mean_red, cov_red, 5000)
  30. # df_red = pd.DataFrame.from_records(pos_red, columns = ['x','y'])
  31. # df_red['colour'] = 'red'
  32. # voter_groups.append(df_red)
  33. #
  34. # mean_green = [0, -5]
  35. # cov_green = [[5, 0], [0, 5]]  # diagonal covariance
  36. # pos_green = np.random.multivariate_normal(mean_green, cov_green, 5000)
  37. # df_green = pd.DataFrame.from_records(pos_green, columns = ['x','y'])
  38. # df_green['colour'] = 'green'
  39. # voter_groups.append(df_green)
  40. #
  41. # mean_blue = [2.5*np.sqrt(3), 2.5]
  42. # cov_blue = [[5, 0], [0, 5]]  # diagonal covariance
  43. # pos_blue = np.random.multivariate_normal(mean_blue, cov_blue, 5000)
  44. # df_blue = pd.DataFrame.from_records(pos_blue, columns = ['x','y'])
  45. # df_blue['colour'] = 'blue'
  46. # voter_groups.append(df_blue)
  47. #
  48. # candidates = [['A',0,0],
  49. #                 ['Z',0,2.5],
  50. #                 ['R1',-1*np.sqrt(3), 1],
  51. #                 ['R2',-2.5*np.sqrt(3), 2.5],
  52. #                 ['R3',-4*np.sqrt(3), 4],
  53. #                 ['G1',0, -2],
  54. #                 ['G2',0, -5],
  55. #                 ['G3',0, -8],
  56. #                 ['B1',1*np.sqrt(3), 1],
  57. #                 ['B2',2.5*np.sqrt(3),2.5],
  58. #                 ['B3',4*np.sqrt(3), 4]]
  59.  
  60. #4 parties
  61. mean_red = [-1.5, 1.5]
  62. cov_red = [[1, 0], [0, 1]]  # diagonal covariance
  63. pos_red = np.random.multivariate_normal(mean_red, cov_red, 4000)
  64. df_red = pd.DataFrame.from_records(pos_red, columns = ['x','y'])
  65. df_red['colour'] = 'red'
  66. voter_groups.append(df_red)
  67.  
  68. mean_green = [-1.5, -1.5]
  69. cov_green = [[1, 0], [0, 1]]  # diagonal covariance
  70. pos_green = np.random.multivariate_normal(mean_green, cov_green, 1500)
  71. df_green = pd.DataFrame.from_records(pos_green, columns = ['x','y'])
  72. df_green['colour'] = 'green'
  73. voter_groups.append(df_green)
  74.  
  75. mean_blue = [1.5, 1.5]
  76. cov_blue = [[1, 0], [0, 1]]  # diagonal covariance
  77. pos_blue = np.random.multivariate_normal(mean_blue, cov_blue, 2000)
  78. df_blue = pd.DataFrame.from_records(pos_blue, columns = ['x','y'])
  79. df_blue['colour'] = 'blue'
  80. voter_groups.append(df_blue)
  81.  
  82. mean_yellow = [1.5, -1.5]
  83. cov_yellow = [[1, 0], [0, 1]]  # diagonal covariance
  84. pos_yellow = np.random.multivariate_normal(mean_yellow, cov_yellow, 2500)
  85. df_yellow = pd.DataFrame.from_records(pos_yellow, columns = ['x','y'])
  86. df_yellow['colour'] = 'yellow'
  87. voter_groups.append(df_yellow)
  88.  
  89. candidates = [
  90.                 ['A',0,0],
  91.                 ['Z1',0,0.5],
  92.                 ['Z2',0,1.5],
  93.                 ['Z3',0,2.5],
  94.                 ['R1',-0.5, 0.5],
  95.                 ['R2',-1.5, 1.5],
  96.                 ['R3',-2.5, 2.5],
  97.                 ['G1',-0.5, -0.5],
  98.                 ['G2',-1.5, -1.5],
  99.                 ['G3',-2.5, -2.5],
  100.                 ['B1',0.5, 0.5],
  101.                 ['B2',1.5, 1.5],
  102.                 ['B3',2.5, 2.5],
  103.                 ['Y1',0.5, -0.5],
  104.                 ['Y2',1.5, -1.5],
  105.                 ['Y3',2.5, -2.5]
  106.                                         ]
  107.  
  108. df_can = pd.DataFrame.from_records(candidates, columns = ['Name','x','y'] )
  109.  
  110. fig = plt.figure(figsize=(20,10))
  111. fig.suptitle('Political Simulation')
  112.  
  113. #image
  114. try:
  115.     ax1 = fig.add_subplot(1, 2, 1)
  116.     img=mpimg.imread('Political Compass.jpg')
  117.     ax1.imshow(img)
  118.     ax1.axis('off')
  119. except:
  120.     print('image missing')
  121.    
  122. # Scatter plot
  123. ax2 = fig.add_subplot(1, 2, 2)
  124. ax2.plot(df_red['x'],df_red['y'],".",label = 'Red', color='r')
  125. ax2.plot(df_green['x'],df_green['y'],".",label = 'Green', color='g')
  126. ax2.plot(df_blue['x'],df_blue['y'],".",label = 'Blue', color='b')
  127. ax2.plot(df_yellow['x'],df_yellow['y'],".",label = 'Yellow', color='y')
  128.  
  129. #Candidates
  130. for c in candidates:
  131.     ax2.plot(c[1], c[2],marker=TextPath((0,0), c[0]),markersize=20, color='k')
  132.  
  133. ax2.set_xlim(-10, 10)
  134. ax2.set_ylim(-10, 10)    
  135. ax2.set_title('Political Compass')
  136. ax2.set_xlabel('Planned Economy  <--  Economics  -->  Free Market')
  137. ax2.set_ylabel('Liberal  <-- Government  --> Authoritarian')    
  138. lgd2 = ax2.legend(loc=1)
  139. fig.savefig("Simulated_Spectrum", dpi=300)
  140.  
  141. if centerists:
  142.     mean_center = [0,0]
  143.     cov_center = [[5, 0], [0, 5]]  # diagonal covariance
  144.     pos_center = np.random.multivariate_normal(mean_center, cov_center, 3500)
  145.     df_center = pd.DataFrame.from_records(pos_center, columns = ['x','y'])
  146.     df_center['colour'] = 'center'
  147.     voter_groups.append(df_center)
  148.    
  149. df_voters = pd.concat(voter_groups,ignore_index=True)
  150.  
  151. #Number of voters
  152. V = df_voters.shape[0]
  153.  
  154. #Make 3d plot of df_voters
  155. fig2 = plt.figure(figsize=(20,10))
  156. fig2.suptitle('Voter Density')
  157.  
  158. #histogram
  159. axa = fig2.add_subplot(121, projection='3d')
  160. hist, xedges, yedges = np.histogram2d(df_voters['x'], df_voters['y'], bins=20, range=[[-10, 10], [-10, 10]])
  161. xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25, indexing="ij")
  162. xpos = xpos.ravel()
  163. ypos = ypos.ravel()
  164. zpos = 0
  165.  
  166. # Construct arrays with the dimensions for the bars.
  167. dx = dy = 0.5 * np.ones_like(zpos)
  168. dz = hist.ravel()
  169.  
  170. axa.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average')
  171. axa.set_xlabel('Economic')
  172. axa.set_ylabel('Government')
  173. axa.set_zlabel('Voter Count')
  174. axa.view_init(35, 240)
  175.  
  176. #surface
  177. X, Y = np.meshgrid(xedges[:-1] + 0.5, yedges[:-1] + 0.5, indexing="ij")
  178.  
  179. axb = fig2.add_subplot(122, projection='3d')
  180. surf = axb.plot_surface(X, Y, hist, cmap="jet", linewidth=0, antialiased=False)
  181. surf.set_edgecolors(surf.to_rgba(surf._A))
  182. #surf.set_facecolors("white")
  183. #cset = axb.contour(X, Y, hist, zdir='z', offset=-100, cmap=cm.coolwarm)
  184. #cset = axb.contour(X, Y, hist, zdir='x', offset=-40, cmap=cm.coolwarm)
  185. #cset = axb.contour(X, Y, hist, zdir='y', offset=40, cmap=cm.coolwarm)
  186. axb.set_xlabel('Economic')
  187. axb.set_ylabel('Government')
  188. axb.set_zlabel('Voter Count')
  189. axb.view_init(35, 240)
  190. fig2.colorbar(ax = axb, mappable = surf, shrink=0.5, aspect=5)
  191. fig2.savefig("3D_Population", dpi=300)
  192.        
  193. distance = pd.DataFrame()
  194. S = pd.DataFrame()
  195.        
  196. for c in candidates:
  197.     distance[c[0]] = df_voters[['x', 'y']].sub(np.array([c[1], c[2]])).pow(2).sum(1).pow(0.5)    
  198.     S[c[0]] = round(np.clip(K - distance[c[0]], 0, np.inf))
  199.  
  200. #rowwise max set to 5
  201. if maximize:
  202.     columns = distance.idxmin('columns')
  203.     for index in S.index:
  204.         S.loc[index,columns[index]] = 5
  205.  
  206. #define seleciton algorithm
  207. def get_winners(S_in,Selection = 'Utilitarian'):
  208.     print('Selection type = ' + Selection)
  209.     score_remaining = np.ones(V)
  210.     print('Hare Quota', V/W)
  211.     print('Total Score Remaining ',score_remaining.sum())
  212.     print('~~~~~~~~~~~~~~~~~~')
  213.     winner_list = []
  214.     while len(winner_list) < W:
  215.  
  216.         #select winner
  217.         #w = index with highest selection metric
  218.         if Selection == 'Monroe':
  219.             w = pd.DataFrame.from_records(np.sort(S_in.values, axis=0), columns = S_in.columns).tail(round(V/W)).sum().idxmax()
  220.         else:            
  221.             w = S_in.sum().idxmax()
  222.        
  223.         #print( sum_scores)  
  224.                    
  225.         print('Winner',w)
  226.            
  227.         winner_list.append(w)
  228.         surplus_factor = max( S_in.sum()[w] *W/V , 1)
  229.    
  230.         #Score spent on each winner by each voter
  231.         score_spent = S_in[w]/ surplus_factor
  232.         print('Score Spent ',score_spent.sum())
  233.        
  234.         #Total score left to be spent by each voter
  235.         score_remaining = np.clip(score_remaining-score_spent,0,1)
  236.         print('Score Remaining ',score_remaining.sum())
  237.         print('------------------')
  238.        
  239.         #Update Ballots
  240.         #set scores to zero for winner so they don't win again
  241.         #S_in[w]=0
  242.         #Take score off of ballot (ie reweight)
  243.    
  244.         for c in S_in.columns:
  245.             S_in[c] = pd.DataFrame([S_in[c], score_remaining]).min()
  246.            
  247.     print(Selection + ' Winner set is:')
  248.     print(winner_list)
  249.     print(' ')    
  250.     return winner_list
  251.  
  252. default_winners = get_winners(S_in=S.divide(K).copy(),Selection = 'Utilitarian')
  253. monroe_winners = get_winners(S_in=S.divide(K).copy(),Selection = 'Monroe')
  254.        
  255. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement