@@ -35,6 +35,11 @@ def pretty_plant_name(row):
3535 return f"{ row .plant_name_eia } (id={ row .plant_id_eia } )"
3636
3737
38+ @app .function
39+ def pretty_value_counts (series ):
40+ return ", " .join (f"{ k } ({ v } )" for k ,v in series .value_counts ().to_dict ().items ())
41+
42+
3843@app .cell
3944def _ (mo , pudl ):
4045 with mo .status .progress_bar (total = 4 , title = "Loading data" , subtitle = "out_eia__yearly_plants" , remove_on_exit = True ) as bar :
@@ -105,7 +110,7 @@ def _(mo, out_eia__yearly_plants, selected_plant):
105110 str (i ): i
106111 for i in available_years
107112 },
108- label = "Data as of :" ,
113+ label = "Report date :" ,
109114 value = str (available_years .iloc [0 ])
110115 )
111116 return (selected_year ,)
@@ -129,11 +134,13 @@ def _(
129134 this_plant = this_plant .rename (pretty_plant_name (this_plant ))
130135
131136 this_plant__monthly_generation_fuel_combined = out_eia923__monthly_generation_fuel_combined .loc [
132- out_eia923__monthly_generation_fuel_combined .plant_id_eia == selected_plant .value
137+ (out_eia923__monthly_generation_fuel_combined .plant_id_eia == selected_plant .value ) &
138+ (out_eia923__monthly_generation_fuel_combined .report_date .dt .year <= selected_year .value .year )
133139 ]
134140
135141 this_plant__monthly_generation = out_eia923__monthly_generation .loc [
136- (out_eia923__monthly_generation .plant_id_eia == selected_plant .value )
142+ (out_eia923__monthly_generation .plant_id_eia == selected_plant .value ) &
143+ (out_eia923__monthly_generation .report_date .dt .year <= selected_year .value .year )
137144 ]
138145
139146 this_plant__generators = out_eia__yearly_generators .loc [
@@ -149,7 +156,8 @@ def _(
149156 this_plant__summary = pd .Series ({
150157 "fuel_types" : ", " .join (this_plant__monthly_generation_fuel_combined .fuel_type_code_pudl .unique ()),
151158 "generators" : this_plant__generators .shape [0 ],
152- "technologies" : ", " .join (this_plant__generators .technology_description .dropna ().drop_duplicates ())
159+ "status" : pretty_value_counts (this_plant__generators .operational_status ),
160+ "technologies" : pretty_value_counts (this_plant__generators .technology_description .dropna ())
153161 }, name = this_plant .name )
154162
155163 mo .vstack ([
@@ -201,7 +209,7 @@ def _(alt, mo, this_plant, this_plant__monthly_generation_fuel_combined):
201209 alt .Y ("net_generation_mwh" , aggregate = "sum" ).title ("Net Generation (MWh)" ),
202210 ).properties (title = f"Total: { this_plant .name } , { this_plant ['city' ]} , { this_plant ['state' ]} " )
203211 mo .output .append (mo .ui .altair_chart (plant_netgen_chart ))
204-
212+
205213 plant_netgen_bysource_chart = alt .Chart (this_plant__monthly_generation_fuel_combined ).mark_line ().encode (
206214 alt .X ("report_date" ).title ("Report date" ),
207215 alt .Y ("net_generation_mwh" , aggregate = "sum" ).title ("Net Generation (MWh)" ),
@@ -244,7 +252,8 @@ def _(mo, this_plant__generators):
244252 filters = {}
245253 only_option = set ()
246254 for k ,v in nonmeasurement_counts .to_dict ().items ():
247- available = this_plant__generators [k ].value_counts (dropna = False ).index
255+ available = this_plant__generators [k ].value_counts (dropna = False )
256+ available = available .loc [available > 0 ].index
248257 if available .shape [0 ]== 1 :
249258 only_option .add (k )
250259 filters [k ] = mo .ui .multiselect (options = {str (x ): x for x in available }, value = [str (available [0 ])] if k in only_option else None )
@@ -254,31 +263,40 @@ def _(mo, this_plant__generators):
254263
255264@app .cell
256265def _ (filters , functools , itertools , mo , only_option , this_plant__generators ):
257- mo .output .append (
258- mo .hstack ([
259- mo .vstack ([
260- mo .hstack ([mo .md (f [0 ]).right (), f [1 ]], widths = [1.1 ,1 ]).style ({"color" :"#bbbbbb" } if f [0 ] in only_option else {})
261- for f in row if f
262- ])
263- for row in itertools .zip_longest (* itertools .batched (filters .items (), 3 ))
264- ], widths = [0.65 ,1 ,1 ])
265- )
266- selected__generators = this_plant__generators [
267- functools .reduce (
268- lambda accum , update : accum & update ,
269- [
270- this_plant__generators [k ].isin (v .value )
271- for k ,v in filters .items () if v .value
272- ]
266+ if len (filters )== 0 :
267+ mo .output .append (mo .md ("No other information about generators for this plant." ).style ({"background" :"#fee" }))
268+ else :
269+ import math
270+ max_column = max ((len (k ) + max (len (vk ) for vk in v .options )) for k ,v in filters .items ())
271+ max_label = max (len (k ) for k ,v in filters .items ())
272+ max_input = max (max (len (vk ) for vk in v .options ) for v in filters .values ())
273+ columns = math .ceil (80 / max_column )
274+
275+ mo .output .append (
276+ mo .hstack ([
277+ mo .vstack ([
278+ mo .hstack ([mo .md (f [0 ]).right (), f [1 ]], widths = [max_label / max_input , 1 ]).style ({"color" :"#bbbbbb" } if f [0 ] in only_option else {})
279+ for f in row if f
280+ ])
281+ for row in itertools .batched (filters .items (), math .ceil (len (filters )/ columns ))
282+ ], widths = "equal" )
273283 )
274- ]
275- mo .output .append (mo .hstack ([
276- mo .md (
277- "All" if selected__generators .shape [0 ] == this_plant__generators .shape [0 ]
278- else f"{ selected__generators .shape [0 ]} of"
279- ),
280- mo .md (f"{ this_plant__generators .shape [0 ]} generators selected" )
281- ], justify = "start" ).style (background = "#eee" ))
284+ selected__generators = this_plant__generators [
285+ functools .reduce (
286+ lambda accum , update : accum & update ,
287+ [
288+ this_plant__generators [k ].isin (v .value )
289+ for k ,v in filters .items () if v .value
290+ ]
291+ )
292+ ]
293+ mo .output .append (mo .hstack ([
294+ mo .md (
295+ "All" if selected__generators .shape [0 ] == this_plant__generators .shape [0 ]
296+ else f"{ selected__generators .shape [0 ]} of"
297+ ),
298+ mo .md (f"{ this_plant__generators .shape [0 ]} generators selected" )
299+ ], justify = "start" ).style (background = "#eee" ))
282300 return (selected__generators ,)
283301
284302
@@ -297,18 +315,26 @@ def _(this_plant__generators):
297315 ]+ [f"energy_source_code_{ i } " for i in range (1 ,7 )]
298316 ignore_columns = [
299317 "operational_status_code" ,
300-
301318 ]
302319 remaining_columns = ["generator_id" ] + sorted (set (this_plant__generators .columns ) - set (ops_columns + nrg_columns ))
303320 return nrg_columns , ops_columns , remaining_columns
304321
305322
306323@app .cell
307- def _ (mo , nrg_columns , ops_columns , remaining_columns , selected__generators ):
308- mo .output .append (mo .ui .table (
309- selected__generators [
310- ops_columns + nrg_columns [1 :]+ remaining_columns [1 :]
311- ].set_index ("generator_id" ).T .dropna (thresh = 1 )))
324+ def _ (
325+ filters ,
326+ mo ,
327+ nrg_columns ,
328+ ops_columns ,
329+ remaining_columns ,
330+ selected__generators ,
331+ ):
332+ if filters .value :
333+ mo .output .append (mo .ui .table (
334+ selected__generators [
335+ ops_columns + nrg_columns [1 :]+ remaining_columns [1 :]
336+ ].set_index ("generator_id" ).T .dropna (thresh = 1 )
337+ ))
312338 return
313339
314340
0 commit comments