Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planned solar projects #45

Merged
merged 15 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ ilsfa_updated: "Apr 2024"
eia860_updated: "Mar 2024"
total_kw: "2,286,000"
planned_kw: "5,625,083"
total_count: "61,909"
gems:
- jekyll-redirect-from
2 changes: 1 addition & 1 deletion about.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h1>About Illinois Solar Map</h1>
As of {{ site.last_updated }}, over <strong>{{ site.total_kw }} kilowatts</strong> of operating solar capacity have been installed in the State of Illinois, with <strong>{{site.planned_kw}} kilowatts planned</strong> or under construction. For comparison, <a href="https://prairiestateenergycampus.com/">Prairie State</a>, the State’s largest coal power plant, is 1,630,000 kilowatts, illustrating just how far we've come in a few years, but still how far we have to go to reach 100% renewable energy in Illinois.
</p>

<p>There are nearly 62,000 solar projects throughout the state, ranging in size from a single 0.6 kW solar panel to the 200,000 kW (200 megawatts) <a href='https://pv-magazine-usa.com/2021/12/17/prairie-wolf-solar-project-begins-operation-in-illinois/'>Prairie Wolf Solar project</a> in Coles County.</p>
<p>There are {{site.total_count}} solar projects throughout the state, ranging in size from a single 0.6 kW solar panel to the 200,000 kW (200 megawatts) <a href='https://pv-magazine-usa.com/2021/12/17/prairie-wolf-solar-project-begins-operation-in-illinois/'>Prairie Wolf Solar project</a> in Coles County.</p>

<p class="text-center">
<img src="/images/prarie-wolf-solar.jpg" class="img-fluid img-thumbnail" alt="The Prarie Wolf Solar Project in Coles County">
Expand Down
8 changes: 8 additions & 0 deletions data/scripts/aggregate_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@
for c in counties:
counties[c]["county_name"] = county_fips[c]

# aggregate by US Census Tract
tracts = {}
aggregate_projects(tracts, "census_tract", "census_tract")
print("aggregated", len(tracts), "tracts")

# aggregate by US Census Place
places = {}
aggregate_projects(places, "place", "place")
print("aggregated", len(tracts), "places")

# aggregate by IL House
house_districts = {}
aggregate_projects(house_districts, "house_district", "house_district")
print("aggregated", len(house_districts), "house districts")
Expand All @@ -47,6 +50,7 @@
house_districts[h]["date_assumed_office"] = di['Date assumed office']
housefile.seek(0)

# aggregate by IL Senate
senate_districts = {}
aggregate_projects(senate_districts, "senate_district", "senate_district")
print("aggregated", len(senate_districts), "senate districts")
Expand All @@ -65,6 +69,10 @@
senate_districts[s]["date_assumed_office"] = di['Date assumed office']
senatefile.seek(0)

# each aggregate shares a common set of fields including:
# energized vs planned
# categories (dg_small, dg_large, cs, utility, total)
# kw totals and project counts
common_field_names = [ "dg_small_kw",
"dg_small_count",
"dg_large_kw",
Expand Down
8 changes: 7 additions & 1 deletion data/scripts/aggregate_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pandas as pd

def init_aggregate(row):
"""initialize an aggregate row"""
agg = {}
agg["dg_small_kw"] = 0
agg["dg_small_count"] = 0
Expand Down Expand Up @@ -49,7 +50,7 @@ def init_aggregate(row):
return agg

def increment_aggregate(agg, row):

"""increment values for an aggregate row"""
prefix = ""
if row["type"] == "planned":
prefix = "planned_"
Expand All @@ -73,6 +74,7 @@ def increment_aggregate(agg, row):
return agg

def aggregate_projects(items, index, index_name):
"""iterates through all projects and aggregates by a given geography"""
projects = []
planned_projects = []

Expand Down Expand Up @@ -103,13 +105,15 @@ def aggregate_projects(items, index, index_name):
continue

def write_csv(items, fields, filename):
"""output aggregates as a csv file"""
with open(filename, "w") as outfile:
writer = csv.writer(outfile)
writer.writerow(fields)
for key, value in items.items():
writer.writerow([value[field] for field in fields])

def write_geojson(geosource, key, items, geoout):
"""output aggregates as a geojson file"""
out_geojson = {
"type": "FeatureCollection",
"features": [] }
Expand Down Expand Up @@ -144,6 +148,7 @@ def write_geojson(geosource, key, items, geoout):
json.dump(out_geojson, outfile)

def aggregate_all_projects():
"""calculate totals across the entire state for about page"""
all_projects = {}
with open("../final/all-projects-w-districts.csv", 'r') as csvfile:
projects = csv.DictReader(csvfile)
Expand All @@ -169,6 +174,7 @@ def aggregate_all_projects():
writer.writerow(["Total", f'{all_projects["total_kw"]:,d} kW', '100%', f'{all_projects["total_count"]:,d}'])

def generate_monthly_kw_time_series():
"""calculate aggregated solar by category over time"""
print("Generating monthly time series...")
# load csv into pandas dataframe
df = pd.read_csv("../final/all-projects-w-districts.csv")
Expand Down
5 changes: 5 additions & 0 deletions data/scripts/combine_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
session = requests_cache.CachedSession('geocoding_cache')

def get_category(size_str):
"""The source data categories are unreliable, so we assign a category
based on the kW size of the project. 25 kW and smaller is Small
Distributed Distribution."""
try:
size = float(size_str)
except ValueError:
Expand All @@ -20,6 +23,7 @@ def get_category(size_str):


def clean_number(num_str):
"""remove number formatting and convert nulls to 0"""
try:
num_str = num_str.replace(',', '')
num = float(num_str)
Expand All @@ -30,6 +34,7 @@ def clean_number(num_str):


def get_census_tract(lat, long):
"""use the census geocoder to find a tract based on lat/long"""
try:
r = session.get(
f"https://geocoding.geo.census.gov/geocoder/geographies/coordinates?benchmark=4&format=json&vintage=4&x={lat}&y={long}")
Expand Down
7 changes: 7 additions & 0 deletions data/scripts/get_tract_districts.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

centroids = []

# get gemoetries for each US Census Tract in Illinois
with open("../raw/unique-tracts.csv", 'r') as csvfile:
tracts = csv.DictReader(csvfile)
for tract in tqdm.tqdm(tracts):
Expand All @@ -31,6 +32,7 @@

print(len(centroids),"centroids found")

# assign each tract to a house district based on centroid
house_districts = {}
with open("../raw/il_house_2023.geojson", "r") as geojsonfile:
house_geojson_src = json.load(geojsonfile)["features"]
Expand All @@ -39,6 +41,7 @@

print(len(house_districts), "house districts found")

# assign each tract to a senate district based on centroid
senate_districts = {}
with open("../raw/il_senate_2023.geojson", "r") as geojsonfile:
senate_geojson_src = json.load(geojsonfile)["features"]
Expand All @@ -47,6 +50,8 @@

print(len(senate_districts), "senate districts found")

# assign each tract to a US Census place based on centroid
# this is likely pretty inaccurate outside of large metro areas like Chicago
census_places = {}
with open("../raw/il_places.geojson", "r") as geojsonfile:
places_geojson_src = json.load(geojsonfile)["features"]
Expand All @@ -55,6 +60,7 @@

print(len(census_places), "census places found")

# set geography values for each tract centroid
for centroid in centroids:
point = (centroid['CENTLON'], centroid['CENTLAT'])
for district in house_districts:
Expand All @@ -70,6 +76,7 @@
centroid['place'] = place
break

# for both energized and planned projects, output data appended with geographies
for project_type in ("energized", "planned"):
print("writing districts for", project_type, "projects")

Expand Down
4 changes: 2 additions & 2 deletions js/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ function getTooltip(props){
<tbody>
<tr>
<td>Total</td>
<td><span class='float-end'>${props.total_kw.toLocaleString()}kW</span></td>
<td><span class='float-end'>${props.total_kw.toLocaleString()} kW</span></td>
<td><span class='float-end'>${props.total_count.toLocaleString()}</span></td>
<td><span class='float-end'>${props.planned_total_kw.toLocaleString()}kW</span></td>
<td><span class='float-end'>${props.planned_total_kw.toLocaleString()} kW</span></td>
<td><span class='float-end'>${props.planned_total_count.toLocaleString()}</span></td>
</tr>
<tr>
Expand Down