-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPolitical Compass Plotter.py
92 lines (76 loc) · 3.07 KB
/
Political Compass Plotter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Author: Jolyn Tan
# Contributor: Samuel Lim
# A short program designed to plot data for a political compass test (http://sapplypoliticalcompass.com/).
import pandas as pd
import plotly.express as px
# 4 compulsory header names in the csv file
ECON = 'Raw_Economic'
AUTH = 'Raw_Authority'
PROG = 'Raw_Progressive'
NAME = 'Name'
# File to read from
DATA_FILE = "political_revolution.csv"
ZSCR = 'Z-Score'
def label_color(row):
if row[ECON] < 0 and row[AUTH] > 0:
return 'red'
if row[ECON] > 0 and row[AUTH] > 0:
return 'blue'
if row[ECON] < 0 and row[AUTH] < 0:
return 'green'
if row[ECON] > 0 and row[AUTH] < 0:
return 'purple'
else:
return 'black'
political_data = pd.read_csv(DATA_FILE)
# Note: Even though Raw_Progressive has the range [-15, 15] instead of [-10, 10], it is unnecessary to normalize it.
# This is because Z-Scores self-normalize the data.
# Calculate Euclidean distance of Z-Scores for all values (assuming normal distribution).
# In the absence of more sophisticated statistical analysis, we bluntly assume that all values are independent.
political_data[ZSCR] = (
((political_data[ECON] - political_data[ECON].mean())/political_data[ECON].std()) ** 2 +
((political_data[AUTH] - political_data[AUTH].mean())/political_data[AUTH].std()) ** 2 +
((political_data[PROG] - political_data[PROG].mean())/political_data[PROG].std()) ** 2
) ** 0.5
political_data = political_data.round(4)
# Print values for min and max Z-Score
print("""
Minimum RMS:
{}
Maximum RMS:
{}
""".format(
political_data[political_data[ZSCR] == political_data[ZSCR].min()],
political_data[political_data[ZSCR] == political_data[ZSCR].max()]
))
# Add average point value
political_data_averages = pd.DataFrame({
NAME: ["AVERAGE"],
ECON: [political_data.mean()[ECON]],
AUTH: [political_data.mean()[AUTH]],
PROG: [political_data.mean()[PROG]],
ZSCR: 0 # by definition
}).round(4)
political_data = political_data.append(political_data_averages, ignore_index=True, sort=False)
print("""
Average Values:
{}
""".format(political_data_averages))
# Transform Progressive data to color
political_data['Color'] = political_data.apply(lambda row: label_color(row), axis = 1)
# Display and format plot
plotlyFig = px.scatter(political_data, x=ECON, y=AUTH, color=PROG,
hover_name=NAME, hover_data={"Color": False, PROG: True, ZSCR: True},
labels = {PROG:"Progressive"}, range_color=[-15, 15], text=NAME)
plotlyFig.update_traces(marker=dict(size=12), textposition='top center')
plotlyFig.update_xaxes(range=[-10, 10],zeroline=True, zerolinewidth=2, zerolinecolor='Black', nticks=20)
plotlyFig.update_yaxes(range=[-10, 10], zeroline=True, zerolinewidth=2, zerolinecolor='Black', nticks=20)
plotlyFig.update_layout(
autosize=False,
width=1200,
height=1200,
xaxis_title = 'Economic',
yaxis_title = 'Authority',
showlegend = False
)
plotlyFig.show()