Skip to content

Commit

Permalink
Work on polling objects and rearrangement of text
Browse files Browse the repository at this point in the history
  • Loading branch information
technocrat committed Apr 25, 2024
1 parent 6366803 commit 89e0980
Show file tree
Hide file tree
Showing 43 changed files with 1,877 additions and 138 deletions.
Binary file added _assets/img/maps/base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_az.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_ga.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_ga_mi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_mi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_nc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_nv.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_pa.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_pa_nc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _assets/img/maps/no_wi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 52 additions & 1 deletion _assets/scripts/aggreg.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const DESIGN_ERROR = 0.012


struct Poll
biden_support::Float64
trump_support::Float64
Expand Down Expand Up @@ -40,6 +39,31 @@ end
# Serialize
# bson("savit.bson",polls_structure)
#

"""
margin_of_error(sample_size::Int64)
Calculates the margin of error for a given sample size, assuming a 95% confidence level and a maximum variability (p = 0.5).
# Arguments
- `sample_size::Int64`: The size of the sample.
# Returns
- `Float64`: The margin of error.
# Notes
- The margin of error is calculated using the formula: sqrt(0.5 * 0.5 / sample_size) + DESIGN_ERROR, where DESIGN_ERROR is a constant representing the design effect or any additional errors introduced by the sampling procedure.
- The formula assumes a 95% confidence level and a maximum variability of 0.5 (i.e., p = 0.5 and q = 0.5, where p is the estimated proportion of the population with the characteristic of interest, and q = 1 - p).
- The margin of error is a measure of the precision of the estimate and represents the maximum expected difference between the true population parameter and the sample estimate, with a certain level of confidence.
# Examples
```julia
julia> margin_of_error(100)
0.09799799799799998
julia> margin_of_error(1000)
0.031623031623031625
"""
function margin_of_error(sample_size)
sqrt(0.5 * 0.5 / sample_size) + DESIGN_ERROR
end
Expand All @@ -57,6 +81,33 @@ polls = [

total_sample_size = sum(poll.sample_size for poll in polls)

"""
weighted_average(polls::Vector{<:AbstractPoll}, candidate::Symbol)
Calculates the weighted average of a candidate's poll results across multiple polls, where
the weights are determined by the inverse of the squared margin of error for each poll.
# Arguments
- `polls::Vector{<:AbstractPoll}`: A vector of poll objects, each containing information about the poll, such as sample size, candidate results, etc.
- `candidate::Symbol`: The symbol representing the candidate for whom the weighted average is to be calculated.
# Returns
- `Float64`: The weighted average of the candidate's poll results.
# Notes
- This function assumes that each poll object has fields named `sample_size` and a field named after the `candidate` symbol, containing the poll result for that candidate.
- The weight for each poll is calculated as `poll.sample_size / (margin_of_error(poll.sample_size)^2)`, which gives more weight to polls with larger sample sizes and smaller margins of error.
- The weighted average is calculated as the sum of (poll result * weight) for all polls, divided by the sum of weights for all polls.
- This method of calculating the weighted average is commonly used in aggregating poll results, as it accounts for the precision of each poll based on its sample size and margin of error.
# Examples
```julia
# Assuming there are two poll objects, `poll1` and `poll2`, with fields `sample_size`, `:candidate1`, and `:candidate2`
polls = [poll1, poll2]
weighted_avg_candidate1 = weighted_average(polls, :candidate1)
weighted_avg_candidate2 = weighted_average(polls, :candidate2)
"""

function weighted_average(polls, candidate)
sum(
getfield(poll, candidate) * poll.sample_size / (margin_of_error(poll.sample_size)^2)
Expand Down
60 changes: 49 additions & 11 deletions _assets/scripts/bayes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,35 @@ struct NormalizedPoll
sample_size::Int
end

"""
normalize_poll(poll::Poll)
Normalizes the poll results for Biden and Trump by dividing their respective support values
by the total support, and returns a `NormalizedPoll` object with the normalized values and sample size.
# Arguments
- `poll::Poll`: A `Poll` object containing the raw poll data, including `biden_support`, `trump_support`, and `sample_size` fields.
# Returns
- `NormalizedPoll`: A `NormalizedPoll` object with the following fields:
- `normalized_biden::Float64`: The normalized support for Biden (between 0 and 1).
- `normalized_trump::Float64`: The normalized support for Trump (between 0 and 1).
- `sample_size::Int64`: The sample size of the poll.
# Notes
- This function assumes that the `Poll` object has fields named `biden_support`, `trump_support`, and `sample_size`.
- The normalization is performed by dividing the `biden_support` and `trump_support` values by the total support (sum of `biden_support` and `trump_support`).
- The normalized values represent the proportion of support for each candidate out of the total support.
- The `NormalizedPoll` object is created with the normalized values and the original `sample_size`.
# Examples
```julia
# Assuming there is a `Poll` object `poll` with fields `biden_support`, `trump_support`, and `sample_size`
normalized_poll = normalize_poll(poll)
println("Normalized Biden support: ", normalized_poll.normalized_biden)
println("Normalized Trump support: ", normalized_poll.normalized_trump)
println("Sample size: ", normalized_poll.sample_size)
"""
function normalize_poll(poll::Poll)
total = poll.biden_support + poll.trump_support
normalized_biden = poll.biden_support / total
Expand All @@ -27,7 +56,7 @@ end
# Define the states and their electoral votes

states = ["PA", "MI", "GA", "NC", "AZ", "WI", "NV"]
electoral_votes = [20, 15, 16, 16, 11, 10, 6]
electoral_votes = [19, 15, 16, 16, 11, 10, 6]

prior_probs = Dict(
"AZ" => 1672143 / (1672143 + 1661686),
Expand All @@ -36,19 +65,19 @@ prior_probs = Dict(
"NC" => 2684292 / (2684292 + 2758775),
"PA" => 3458229 / (3458229 + 3377674),
"WI" => 1630866 / (1630866 + 1610184),
"NV" => 703486 / ( 703486 + 669890)
"NV" => 703486 / ( 703486 + 66989x0)
)

# Define the state_polls dictionary
# Define the state_polls dictionary

state_polls = Dict(
"PA" => [Poll(0.40, 0.46, 1305), Poll(0.45, 0.45, 807), Poll(0.56, 0.46, 520)],
"MI" => [Poll(0.41, 0.45, 1218), Poll(0.45, 0.45, 778), Poll(0.56, 0.46, 1097)],
"GA" => [Poll(0.43, 0.44, 788), Poll(0.48, 0.51, 1133), Poll(0.42, 0.46, 520)],
"NC" => [Poll(0.43, 0.49, 699), Poll(0.42, 0.45, 829), Poll(0.48, 0.51, 1295)],
"AZ" => [Poll(0.43, 0.48, 796), Poll(0.43, 0.47, 1000), Poll(0.45, 0.50, 600)],
"WI" => [Poll(0.46, 0.45, 697), Poll(0.44, 0.46, 1000), Poll(0.45, 0.46, 600)],
"NV" => [Poll(0.44, 0.46, 447), Poll(0.49, 0.51, 1000), Poll(0.48, 0.44, 600)]
"PA" => [Poll(0.40, 0.46, 1305), Poll(0.45, 0.45, 807), Poll(0.56, 0.46, 520)],
"MI" => [Poll(0.41, 0.45, 1218), Poll(0.45, 0.45, 778), Poll(0.56, 0.46, 1097)],
"GA" => [Poll(0.43, 0.44, 788), Poll(0.48, 0.51, 1133), Poll(0.42, 0.46, 520)],
"NC" => [Poll(0.43, 0.49, 699), Poll(0.42, 0.45, 829), Poll(0.48, 0.51, 1295)],
"AZ" => [Poll(0.43, 0.48, 796), Poll(0.43, 0.47, 1000), Poll(0.45, 0.50, 600)],
"WI" => [Poll(0.46, 0.45, 697), Poll(0.44, 0.46, 1000), Poll(0.45, 0.46, 600)],
"NV" => [Poll(0.44, 0.46, 447), Poll(0.49, 0.51, 1000), Poll(0.48, 0.44, 600)]
)

# Normalize the state_polls dictionary
Expand Down Expand Up @@ -91,7 +120,7 @@ end
# Run the inference

model = election_model(normalized_state_polls, prior_probs)
chain = sample(model, NUTS(), 1_000)
chain = sample(model, NUTS(), 10_000)

# Extract the posterior samples
p_samples = Array(chain)
Expand Down Expand Up @@ -124,3 +153,12 @@ plot(chain)
autocor(chain)
ess(chain)



# Column names to round
columns_to_round = [:votes, :low, :mean, :high, :expect]

# Apply rounding using column names
for col_name in columns_to_round
df[!, col_name] = round.(df[!, col_name], digits = 2)
end
9 changes: 9 additions & 0 deletions _assets/scripts/mar_state_dict.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
state_polls = Dict(
"PA" => [Poll(0.40, 0.46, 1305), Poll(0.45, 0.45, 807), Poll(0.56, 0.46, 520)],
"MI" => [Poll(0.41, 0.45, 1218), Poll(0.45, 0.45, 778), Poll(0.56, 0.46, 1097)],
"GA" => [Poll(0.43, 0.44, 788), Poll(0.48, 0.51, 1133), Poll(0.42, 0.46, 520)],
"NC" => [Poll(0.43, 0.49, 699), Poll(0.42, 0.45, 829), Poll(0.48, 0.51, 1295)],
"AZ" => [Poll(0.43, 0.48, 796), Poll(0.43, 0.47, 1000), Poll(0.45, 0.50, 600)],
"WI" => [Poll(0.46, 0.45, 697), Poll(0.44, 0.46, 1000), Poll(0.45, 0.46, 600)],
"NV" => [Poll(0.44, 0.46, 447), Poll(0.49, 0.51, 1000), Poll(0.48, 0.44, 600)]
)
94 changes: 94 additions & 0 deletions _assets/scripts/multi_color_map.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using PlotlyJS

const STATES = ["NV", "WI", "AZ", "GA", "MI", "PA", "NC"]

const VOTES = [6, 10, 11, 16, 15, 19, 16]

const TIED = 269

const FLAGRED = "rgb(178, 34, 52)"

const FLAGBLUE = "rgb(60, 59, 110)"

const PURPLE = "rgb(119, 47, 81)"

const GREENBAR = "rgb(47, 119, 78)"

const STATE_COLORS = Dict(
"PA" => FLAGRED,
"NC" => FLAGRED,
"NV" => PURPLE,
"MI" => PURPLE,
"WI" => PURPLE,
"AZ" => PURPLE,
"GA" => PURPLE
)

votes = Dict(
"NV" => 6,
"MI" => 15,
"WI" => 10,
"NC" => 16,
"AZ" => 11,
"PA" => 19,
"GA" => 16
)

data = [votes[state] for state in STATES]

function electoral_map_with_colors(data, state_colors)
# Create the data for the choropleth map
choropleth_trace = PlotlyJS.choropleth(
locationmode="USA-states",
locations=STATES,
z=data,
colorscale=[[0, "rgba(0,0,0,0)"], [1, "rgba(0,0,0,0)"]],
showscale=false,
marker=attr(line=attr(color="white", width=2)),
hoverinfo="location+text"
)

# Create the data for the state colors
color_traces = [
PlotlyJS.choropleth(
locationmode="USA-states",
locations=[state],
z=[1],
colorscale=[[0, color], [1, color]],
showscale=false,
marker=attr(line=attr(color="white", width=2)),
hoverinfo="none"
)
for (state, color) in state_colors
]

# Create the data for the state labels
label_trace = PlotlyJS.scattergeo(
locationmode="USA-states",
locations=STATES,
text=data,
textfont=attr(size=12, color="white"),
mode="text",
showlegend=false,
hoverinfo="none"
)

# Create the layout for the map
layout = PlotlyJS.Layout(
title= "Without PA & NC: 58 Swing State Electoral Votes (45 required to win)",
geo=attr(
scope="usa",
projection=attr(type="albers usa"),
showlakes=true,
lakecolor="rgb(255, 255, 255)"
)
)

# Create the figure with all traces
fig = PlotlyJS.plot(vcat(choropleth_trace, color_traces..., label_trace), layout)

# Save the plot as an image file
PlotlyJS.savefig(fig, "/Users/ro/projects/SwingWatch/_assets/img/maps/no_pa_nc.png")
end

electoral_map_with_colors(data, STATE_COLORS)
Loading

0 comments on commit 89e0980

Please sign in to comment.