import%20marimo%0A%0A__generated_with%20%3D%20%220.16.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20polars%20as%20pl%0A%20%20%20%20import%20plotly.express%20as%20px%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%20%23%20For%20question%201%0A%20%20%20%20import%20os%0A%20%20%20%20import%20json%2C%20ast%0A%20%20%20%20import%20lets_plot%0A%20%20%20%20import%20importlib%0A%20%20%20%20from%20plotly.subplots%20import%20make_subplots%20%23%20Load%20in%20the%20final%20html%0A%20%20%20%20return%20go%2C%20lets_plot%2C%20mo%2C%20os%2C%20pl%2C%20px%0A%0A%0A%40app.cell%0Adef%20_(lets_plot)%3A%0A%0A%20%20%20%20%23%20Get%20the%20__all__%20list%20from%20lets_plot%0A%20%20%20%20all_symbols%20%3D%20lets_plot.__all__%0A%0A%20%20%20%20%23%20Import%20each%20symbol%20into%20the%20current%20namespace%0A%20%20%20%20for%20symbol%20in%20all_symbols%3A%0A%20%20%20%20%20%20%20%20globals()%5Bsymbol%5D%20%3D%20getattr(lets_plot%2C%20symbol)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pl)%3A%0A%20%20%20%20df%20%3D%20pl.DataFrame(%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22A%22%3A%20%5B%22a%22%2C%20%22b%22%2C%20%22a%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22B%22%3A%20%5B1%2C%203%2C%205%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22C%22%3A%20%5B10%2C%2011%2C%2012%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22D%22%3A%20%5B2%2C%204%2C%206%5D%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20)%0A%20%20%20%20df%0A%20%20%20%20return%20(df%2C)%0A%0A%0A%40app.cell%0Adef%20_(aes%2C%20df%2C%20geom_line%2C%20geom_point%2C%20ggplot%2C%20ggsize%2C%20ggtb)%3A%0A%20%20%20%20ggplot(df%2C%20aes(x%3D%22B%22%2C%20y%3D%22C%22))%20%2B%20geom_point()%20%2B%20%5C%0A%20%20%20%20%20%20%20%20geom_line()%20%2B%20%5C%0A%20%20%20%20%20%20%20%20ggtb()%20%2B%20%5C%0A%20%20%20%20%20%20%20%20ggsize(width%3D1000%2C%20height%3D500)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(os)%3A%0A%0A%20%20%20%20os.listdir()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(os)%3A%0A%20%20%20%20%23%20These%20are%20the%20two%20primary%20files%20you%20have%20to%20use%20in%20the%20project.%0A%20%20%20%20os.listdir('data%2Fparquet')%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pl)%3A%0A%20%20%20%20places%20%3D%20pl.read_parquet('data%2Fparquet%2Fplaces.parquet')%0A%20%20%20%20patterns%20%3D%20pl.read_parquet('data%2Fparquet%2Fpatterns.parquet')%0A%20%20%20%20return%20patterns%2C%20places%0A%0A%0A%40app.cell%0Adef%20_(places)%3A%0A%20%20%20%20places%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(patterns)%3A%0A%20%20%20%20patterns%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(patterns%2C%20pl%2C%20places)%3A%0A%20%20%20%20%23%20----------%20QUICK%20DATA%20QUALITY%20CHECK%20----------%0A%0A%20%20%20%20def%20run_data_quality_report(places_df%3A%20pl.DataFrame%2C%20patterns_df%3A%20pl.DataFrame)%3A%0A%20%20%20%20%20%20%20%20def%20_first_present(df%2C%20cands)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20next((c%20for%20c%20in%20cands%20if%20c%20in%20df.columns)%2C%20None)%0A%0A%20%20%20%20%20%20%20%20def%20_print_section(t)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%5Cn%22%20%2B%20%22%3D%22*80%20%2B%20f%22%5Cn%7Bt%7D%5Cn%22%20%2B%20%22%3D%22*80)%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20Basic%20shape%20----------------%0A%20%20%20%20%20%20%20%20_print_section(%22BASIC%20SHAPE%22)%0A%20%20%20%20%20%20%20%20print(f%22PLACES%3A%20%20%20%7Bplaces_df.height%3A%2C%7D%20rows%20%C3%97%20%7Bplaces_df.width%7D%20cols%22)%0A%20%20%20%20%20%20%20%20print(f%22PATTERNS%3A%20%7Bpatterns_df.height%3A%2C%7D%20rows%20%C3%97%20%7Bpatterns_df.width%7D%20cols%22)%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20Column%20summary%20----------------%0A%20%20%20%20%20%20%20%20def%20_summ(df%2C%20name)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_print_section(f%22COLUMN%20SUMMARY%20%E2%80%94%20%7Bname%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20c%2C%20dt%20in%20df.schema.items()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20n%20%3D%20df%5Bc%5D.null_count()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pct%20%3D%20n%20%2F%20df.height%20*%20100%20if%20df.height%20else%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%7Bc%3A35%7D%20%7Bstr(dt)%3A20%7D%20nulls%3D%7Bn%3A%2C%7D%20(%7Bpct%3A.1f%7D%25)%22)%0A%20%20%20%20%20%20%20%20_summ(places_df%2C%22PLACES%22)%0A%20%20%20%20%20%20%20%20_summ(patterns_df%2C%22PATTERNS%22)%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20Join%20keys%20----------------%0A%20%20%20%20%20%20%20%20_print_section(%22JOIN%20KEY%20UNIQUENESS%22)%0A%20%20%20%20%20%20%20%20jk_pat%20%3D%20_first_present(patterns_df%2C%20%5B%22placekey%22%2C%22safegraph_place_id%22%2C%22place_id%22%2C%22poi_id%22%5D)%0A%20%20%20%20%20%20%20%20jk_pla%20%3D%20_first_present(places_df%2C%20%20%20%5B%22placekey%22%2C%22safegraph_place_id%22%2C%22place_id%22%2C%22poi_id%22%5D)%0A%20%20%20%20%20%20%20%20if%20jk_pat%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20uniq_pat%20%3D%20patterns_df.select(pl.col(jk_pat).n_unique())%5B0%2C0%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22PATTERNS%20%7Bjk_pat%7D%3A%20%7Buniq_pat%3A%2C%7D%20unique%20%2F%20%7Bpatterns_df.height%3A%2C%7D%20rows%22)%0A%20%20%20%20%20%20%20%20if%20jk_pla%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20uniq_pla%20%3D%20places_df.select(pl.col(jk_pla).n_unique())%5B0%2C0%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22PLACES%20%20%20%7Bjk_pla%7D%3A%20%7Buniq_pla%3A%2C%7D%20unique%20%2F%20%7Bplaces_df.height%3A%2C%7D%20rows%22)%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20Nested%20fields%20----------------%0A%20%20%20%20%20%20%20%20rel_brand%20%3D%20_first_present(patterns_df%2C%20%5B%22related_same_day_brand%22%2C%22related_same_day_brands%22%5D)%0A%20%20%20%20%20%20%20%20hour_col%20%20%3D%20_first_present(patterns_df%2C%20%5B%22popularity_by_hour%22%2C%22visits_by_each_hour%22%2C%22visits_by_hour%22%5D)%0A%20%20%20%20%20%20%20%20dev_col%20%20%20%3D%20_first_present(patterns_df%2C%20%5B%22device_type%22%2C%22visitor_device_type%22%2C%22mobile_device_type%22%5D)%0A%20%20%20%20%20%20%20%20rvc_col%20%20%20%3D%20_first_present(patterns_df%2C%20%5B%22raw_visit_counts%22%2C%22raw_visits%22%2C%22visits%22%5D)%0A%0A%20%20%20%20%20%20%20%20_print_section(%22KEY%20NESTED%20FIELDS%22)%0A%20%20%20%20%20%20%20%20print(%22related_same_day_brand%3A%22%2C%20rel_brand)%0A%20%20%20%20%20%20%20%20print(%22hourly%20popularity%3A%22%2C%20hour_col)%0A%20%20%20%20%20%20%20%20print(%22device%20column%3A%22%2C%20dev_col)%0A%20%20%20%20%20%20%20%20print(%22raw%20visit%20counts%3A%22%2C%20rvc_col)%0A%0A%20%20%20%20%20%20%20%20if%20rel_brand%3A%20print(%22%5CnSample%20related_same_day_brand%3A%22%2C%20patterns_df.select(rel_brand).head(3))%0A%20%20%20%20%20%20%20%20if%20hour_col%3A%20%20print(%22%5CnSample%20hourly%20field%3A%22%2C%20patterns_df.select(hour_col).head(3))%0A%20%20%20%20%20%20%20%20if%20dev_col%3A%20%20%20print(%22%5CnSample%20device%20field%3A%22%2C%20patterns_df.select(dev_col).head(3))%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20Hour%20vector%20length%20----------------%0A%20%20%20%20%20%20%20%20if%20hour_col%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_print_section(%22HOURLY%20VECTOR%20LENGTH%20CHECK%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20lens%20%3D%20patterns_df.select(pl.col(hour_col).list.len().alias(%22len%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20print(lens.describe())%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20Raw%20visit%20counts%20stats%20----------------%0A%20%20%20%20%20%20%20%20if%20rvc_col%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_print_section(%22RAW%20VISIT%20COUNTS%20SUMMARY%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(patterns_df.select(pl.col(rvc_col)).describe())%0A%0A%20%20%20%20%20%20%20%20%23%20----------------%20State%20coverage%20----------------%0A%20%20%20%20%20%20%20%20state_col%20%3D%20_first_present(places_df%2C%20%5B%22region%22%2C%22state%22%2C%22iso_region%22%2C%22region_abbr%22%2C%22address_region%22%2C%22state_abbrev%22%5D)%0A%20%20%20%20%20%20%20%20if%20state_col%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_print_section(%22STATE%20COVERAGE%20%E2%80%94%20TOP%2020%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(places_df.group_by(state_col).len().sort(%22len%22%2C%20descending%3DTrue).head(20))%0A%0A%20%20%20%20%23%20----%20Run%20----%0A%20%20%20%20run_data_quality_report(places%2C%20patterns)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(go%2C%20mo%2C%20patterns%2C%20pl%2C%20places%2C%20px)%3A%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20%23%201.%20Detect%20columns%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20def%20first_present(tbl%3A%20pl.DataFrame%2C%20cands)%3A%0A%20%20%20%20%20%20%20%20return%20next((c%20for%20c%20in%20cands%20if%20c%20in%20tbl.columns)%2C%20None)%0A%0A%20%20%20%20join_key_patterns%20%3D%20first_present(patterns%2C%20%5B%22placekey%22%2C%20%22safegraph_place_id%22%2C%20%22place_id%22%2C%20%22poi_id%22%5D)%0A%20%20%20%20join_key_places%20%20%20%3D%20first_present(places%2C%20%20%20%5B%22placekey%22%2C%20%22safegraph_place_id%22%2C%20%22place_id%22%2C%20%22poi_id%22%5D)%0A%20%20%20%20state_col%20%20%20%20%20%20%20%20%20%3D%20first_present(places%2C%20%20%20%5B%22region%22%2C%20%22state%22%2C%20%22iso_region%22%2C%20%22region_abbr%22%2C%20%22address_region%22%2C%20%22state_abbrev%22%5D)%0A%20%20%20%20name_col%20%20%20%20%20%20%20%20%20%20%3D%20first_present(places%2C%20%20%20%5B%22brand%22%2C%20%22location_name%22%2C%20%22name%22%2C%20%22poi_name%22%5D)%0A%20%20%20%20cat_col%20%20%20%20%20%20%20%20%20%20%20%3D%20first_present(places%2C%20%20%20%5B%22top_category%22%2C%20%22sub_category%22%2C%20%22naics_code%22%2C%20%22category_tags%22%2C%20%22categories%22%5D)%0A%20%20%20%20device_col%20%20%20%20%20%20%20%20%3D%20first_present(patterns%2C%20%5B%22device_type%22%2C%20%22visitor_device_type%22%2C%20%22mobile_device_type%22%5D)%0A%20%20%20%20hourly_col%20%20%20%20%20%20%20%20%3D%20first_present(patterns%2C%20%5B%22popularity_by_hour%22%2C%22visits_by_each_hour%22%2C%22visits_by_hour%22%5D)%0A%20%20%20%20same_day_col%20%20%20%20%20%20%3D%20first_present(patterns%2C%20%5B%22related_same_day_brand%22%2C%22related_same_day_brands%22%5D)%0A%0A%20%20%20%20places_states%20%3D%20places.filter(pl.col(state_col).is_in(%5B%22UT%22%2C%22GA%22%5D))%0A%0A%20%20%20%20def%20contains_any(expr%3A%20pl.Expr%2C%20subs)%3A%0A%20%20%20%20%20%20%20%20cond%20%3D%20None%0A%20%20%20%20%20%20%20%20for%20s%20in%20subs%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20part%20%3D%20expr.str.contains(s%2C%20literal%3DTrue%2C%20strict%3DFalse)%0A%20%20%20%20%20%20%20%20%20%20%20%20cond%20%3D%20part%20if%20cond%20is%20None%20else%20(cond%20%7C%20part)%0A%20%20%20%20%20%20%20%20return%20cond%0A%0A%20%20%20%20name_expr%20%3D%20pl.col(name_col).cast(pl.Utf8).str.to_lowercase()%0A%20%20%20%20lds_patterns%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%22church%20of%20jesus%20christ%20of%20latter-day%20saints%22%2C%0A%20%20%20%20%20%20%20%20%22church%20of%20jesus%20christ%20of%20latter%20day%20saints%22%2C%0A%20%20%20%20%20%20%20%20%22church%20of%20jesus%20christ%22%2C%0A%20%20%20%20%20%20%20%20%22lds%22%2C%0A%20%20%20%20%20%20%20%20%22seminary%22%2C%0A%20%20%20%20%20%20%20%20%22temple%22%0A%20%20%20%20%5D%0A%20%20%20%20church_patterns%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%22church%22%2C%22baptist%22%2C%22methodist%22%2C%22catholic%22%2C%22lutheran%22%2C%0A%20%20%20%20%20%20%20%20%22presbyterian%22%2C%22episcopal%22%2C%22pentecostal%22%2C%22non-denominational%22%0A%20%20%20%20%5D%0A%0A%20%20%20%20is_lds%20%3D%20contains_any(name_expr%2C%20lds_patterns)%0A%20%20%20%20is_other_by_name%20%3D%20contains_any(name_expr%2C%20church_patterns)%0A%20%20%20%20is_church_by_cat%20%3D%20contains_any(pl.col(cat_col).cast(pl.Utf8).str.to_lowercase()%2C%20%5B%22church%22%2C%22religious%22%2C%22worship%22%5D)%20if%20cat_col%20else%20pl.lit(False)%0A%20%20%20%20is_other_church%20%3D%20(is_other_by_name%20%7C%20is_church_by_cat)%20%26%20(~is_lds)%0A%0A%20%20%20%20lds_subtype%20%3D%20(%0A%20%20%20%20%20%20%20%20pl.when(is_lds%20%26%20name_expr.str.contains(%22temple%22%2C%20literal%3DFalse))%0A%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22LDS%20Temple%22))%0A%20%20%20%20%20%20%20%20.when(is_lds%20%26%20name_expr.str.contains(%22seminary%22%2C%20literal%3DFalse))%0A%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22LDS%20Seminary%22))%0A%20%20%20%20%20%20%20%20.when(is_lds)%0A%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22LDS%20Meetinghouse%22))%0A%20%20%20%20%20%20%20%20.otherwise(pl.lit(None))%0A%20%20%20%20)%0A%0A%20%20%20%20places_labeled%20%3D%20places_states.with_columns(%5B%0A%20%20%20%20%20%20%20%20is_lds.alias(%22is_lds%22)%2C%0A%20%20%20%20%20%20%20%20is_other_church.alias(%22is_other_church%22)%2C%0A%20%20%20%20%20%20%20%20lds_subtype.alias(%22LDS%20Type%22)%0A%20%20%20%20%5D).with_columns(%5B%0A%20%20%20%20%20%20%20%20pl.when(pl.col(%22LDS%20Type%22).is_not_null())%0A%20%20%20%20%20%20%20%20%20%20.then(pl.col(%22LDS%20Type%22))%0A%20%20%20%20%20%20%20%20%20%20.when(pl.col(%22is_other_church%22))%0A%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22Other%20Churches%22))%0A%20%20%20%20%20%20%20%20%20%20.otherwise(pl.lit(%22Other%20POI%22))%0A%20%20%20%20%20%20%20%20%20%20.alias(%22Church%20Group%22)%0A%20%20%20%20%5D).filter(pl.col(%22Church%20Group%22)%20!%3D%20%22Other%20POI%22)%0A%0A%20%20%20%20patt_join%20%3D%20patterns.join(%0A%20%20%20%20%20%20%20%20places_labeled.select(%5Bjoin_key_places%2C%20state_col%2C%20%22Church%20Group%22%2C%20%22LDS%20Type%22%5D)%2C%0A%20%20%20%20%20%20%20%20left_on%3Djoin_key_patterns%2C%20right_on%3Djoin_key_places%2C%20how%3D%22inner%22%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20%23%20Q1%20%E2%80%94%20iOS%20vs%20Android%20(dumbbell)%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20if%20device_col%3A%0A%20%20%20%20%20%20%20%20pj%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20patt_join%0A%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.when(pl.col(%22Church%20Group%22).str.starts_with(%22LDS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22LDS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.when(pl.col(%22Church%20Group%22)%20%3D%3D%20%22Other%20Churches%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22Other%20Churches%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.otherwise(pl.lit(None))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.alias(%22Group2%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20.drop_nulls(%22Group2%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20.explode(device_col)%0A%20%20%20%20%20%20%20%20%20%20%20%20.unnest(device_col)%0A%20%20%20%20%20%20%20%20%20%20%20%20.rename(%7B%22key%22%3A%20%22device_key%22%2C%20%22value%22%3A%20%22device_count%22%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22device_key%22).cast(pl.Utf8).str.to_lowercase().alias(%22device_key%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter(pl.col(%22device_key%22).is_in(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22ios%22%2C%22iphone%22%2C%22apple_ios%22%2C%22android%22%2C%22google%22%2C%22android_phone%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D))%0A%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.when(pl.col(%22device_key%22).is_in(%5B%22ios%22%2C%22iphone%22%2C%22apple_ios%22%5D))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22iOS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.when(pl.col(%22device_key%22).is_in(%5B%22android%22%2C%22google%22%2C%22android_phone%22%5D))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22Android%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.otherwise(pl.lit(None))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.alias(%22Device%20Platform%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20.drop_nulls(%5B%22Device%20Platform%22%5D)%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20q1%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20pj.group_by(%5Bstate_col%2C%20%22Group2%22%2C%20%22Device%20Platform%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20.agg(pl.sum(%22device_count%22).alias(%22Total%20Visits%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22Total%20Visits%22).sum().over(%5Bstate_col%2C%20%22Group2%22%5D).alias(%22Total%20Group%20Visits%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22Total%20Visits%22)%20%2F%20pl.col(%22Total%20Group%20Visits%22)).alias(%22Visit%20Share%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20df_q1%20%3D%20q1.rename(%7Bstate_col%3A%20%22State%22%2C%20%22Group2%22%3A%20%22Church%20Group%22%7D).to_pandas()%0A%0A%20%20%20%20%20%20%20%20fig%20%3D%20go.Figure()%0A%20%20%20%20%20%20%20%20color_map%20%3D%20%7B%22LDS%22%3A%20%22green%22%2C%20%22Other%20Churches%22%3A%20%22gold%22%7D%0A%0A%20%20%20%20%20%20%20%20for%20(state%2C%20group)%2C%20subset%20in%20df_q1.groupby(%5B%22State%22%2C%22Church%20Group%22%5D)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ios%20%3D%20subset.loc%5Bsubset%5B%22Device%20Platform%22%5D%3D%3D%22iOS%22%2C%22Visit%20Share%22%5D.values%0A%20%20%20%20%20%20%20%20%20%20%20%20android%20%3D%20subset.loc%5Bsubset%5B%22Device%20Platform%22%5D%3D%3D%22Android%22%2C%22Visit%20Share%22%5D.values%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20len(android)%3D%3D0%20or%20len(ios)%3D%3D0%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%0A%20%20%20%20%20%20%20%20%20%20%20%20y_label%20%3D%20f%22%7Bstate%7D%20%E2%80%93%20%7Bgroup%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20color_map.get(group%2C%20%22gray%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20fig.add_trace(go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D%5Bandroid%5B0%5D*100%2C%20ios%5B0%5D*100%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3D%5By_label%2C%20y_label%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%2Bmarkers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3Dcolor%2C%20width%3D3)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D12%2C%20color%3D%5Bcolor%2C%20color%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3Dy_label%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showlegend%3DFalse%0A%20%20%20%20%20%20%20%20%20%20%20%20))%0A%0A%20%20%20%20%20%20%20%20fig.update_layout(%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Q1%3A%20iOS%20vs%20Android%20Visit%20Share%20(LDS%20vs%20Other%20Churches)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20xaxis_title%3D%22Visit%20Share%20(%25)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20yaxis_title%3D%22State%20%26%20Church%20Group%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20xaxis%3Ddict(range%3D%5B0%2C%20100%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20template%3D%22simple_white%22%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20mo.ui.plotly(fig)%0A%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20%23%20Q2%20%E2%80%94%20Hourly%20visits%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20if%20hourly_col%3A%0A%20%20%20%20%20%20%20%20rows%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20pj2%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20patt_join%0A%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.when(pl.col(%22Church%20Group%22).str.starts_with(%22LDS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22LDS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.when(pl.col(%22Church%20Group%22)%20%3D%3D%20%22Other%20Churches%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22Other%20Churches%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.otherwise(pl.lit(None))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.alias(%22Group2%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20.drop_nulls(%22Group2%22)%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20for%20state%2C%20grp%2C%20hours%2C%20total%20in%20pj2.select(%5Bstate_col%2C%20%22Group2%22%2C%20hourly_col%2C%20%22raw_visit_counts%22%5D).iter_rows()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(hours%2C%20list)%20and%20total%20is%20not%20None%20and%20sum(x%20for%20x%20in%20hours%20if%20x)%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20scale%20%3D%20total%20%2F%20sum(x%20for%20x%20in%20hours%20if%20x)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20h%2C%20v%20in%20enumerate(hours)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20v%20is%20not%20None%20and%206%20%3C%3D%20h%20%3C%3D%2022%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rows.append((state%2C%20grp%2C%20h%2C%20v%20*%20scale))%0A%0A%20%20%20%20%20%20%20%20if%20rows%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20q2%20%3D%20pl.DataFrame(rows%2C%20schema%3D%5B%22State%22%2C%20%22Church%20Group%22%2C%20%22Hour%22%2C%20%22Visits%22%5D%2C%20orient%3D%22row%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20q2%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20q2.group_by(%5B%22State%22%2C%20%22Church%20Group%22%2C%20%22Hour%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.agg(pl.sum(%22Visits%22).alias(%22Total%20Visits%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.sort(%5B%22State%22%2C%22Church%20Group%22%2C%22Hour%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fig2%20%3D%20px.line(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20q2.to_pandas()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22Hour%22%2C%20y%3D%22Total%20Visits%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22Church%20Group%22%2C%20facet_col%3D%22State%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color_discrete_map%3D%7B%22LDS%22%3A%20%22green%22%2C%20%22Other%20Churches%22%3A%20%22gold%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Q2%3A%20Hourly%20Visit%20Patterns%20(LDS%20vs%20Other%20Churches)%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20fig2.update_traces(mode%3D%22lines%2Bmarkers%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20fig2.update_yaxes(title%3D%22Weighted%20Visits%20per%20Church%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.ui.plotly(fig2)%0A%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20%23%20Q3%20%E2%80%94%20Top%20Same-Day%20Brands%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20if%20same_day_col%3A%0A%20%20%20%20%20%20%20%20rows%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20pj3%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20patt_join%0A%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.when(pl.col(%22Church%20Group%22).str.starts_with(%22LDS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22LDS%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.when(pl.col(%22Church%20Group%22)%20%3D%3D%20%22Other%20Churches%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.then(pl.lit(%22Other%20Churches%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.otherwise(pl.lit(None))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.alias(%22Group2%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20.drop_nulls(%22Group2%22)%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20for%20state%2C%20grp%2C%20brands%20in%20pj3.select(%5Bstate_col%2C%20%22Group2%22%2C%20same_day_col%5D).iter_rows()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(brands%2C%20list)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20b%20in%20brands%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(b%2C%20dict)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20k%20%3D%20b.get(%22key%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v%20%3D%20b.get(%22value%22%2C%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20k%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rows.append((state%2C%20grp%2C%20k%2C%20v))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elif%20hasattr(b%2C%20%22items%22)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20k%2C%20v%20in%20b.items()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rows.append((state%2C%20grp%2C%20k%2C%20v))%0A%0A%20%20%20%20%20%20%20%20if%20rows%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20q3%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.DataFrame(rows%2C%20schema%3D%5B%22State%22%2C%20%22Church%20Group%22%2C%20%22Brand%22%2C%20%22Visits%22%5D%2C%20orient%3D%22row%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.group_by(%5B%22State%22%2C%20%22Church%20Group%22%2C%20%22Brand%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.agg(pl.sum(%22Visits%22).alias(%22Total%20Visits%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.sort(by%3D%5B%22State%22%2C%20%22Church%20Group%22%2C%20%22Total%20Visits%22%5D%2C%20descending%3D%5BFalse%2C%20False%2C%20True%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20top10_q3%20%3D%20q3.group_by(%5B%22State%22%2C%20%22Church%20Group%22%5D).head(10)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fig3%20%3D%20px.bar(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20top10_q3.to_pandas()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22Total%20Visits%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3D%22Brand%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22Church%20Group%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20facet_col%3D%22State%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orientation%3D%22h%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color_discrete_map%3D%7B%22LDS%22%3A%20%22green%22%2C%20%22Other%20Churches%22%3A%20%22gold%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Q3%3A%20Top%20Same-Day%20Brands%20%E2%80%94%20LDS%20vs%20Other%20Churches%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.ui.plotly(fig3)%0A%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20%23%20Q4%20%E2%80%94%20LDS%20Temple%20%2F%20Seminary%20%2F%20Meetinghouse%0A%20%20%20%20%23%20--------------------------------------------------------------------%0A%20%20%20%20if%20same_day_col%3A%0A%20%20%20%20%20%20%20%20rows%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20state%2C%20ldstype%2C%20brands%20in%20patt_join.select(%5Bstate_col%2C%22LDS%20Type%22%2Csame_day_col%5D).iter_rows()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20ldstype%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(brands%2C%20list)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20b%20in%20brands%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(b%2C%20dict)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20k%20%3D%20b.get(%22key%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v%20%3D%20b.get(%22value%22%2C1)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20k%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rows.append((state%2C%20ldstype%2C%20k%2C%20v))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elif%20hasattr(b%2C%20%22items%22)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20k%2Cv%20in%20b.items()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rows.append((state%2C%20ldstype%2C%20k%2C%20v))%0A%20%20%20%20%20%20%20%20if%20rows%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20q4%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pl.DataFrame(rows%2C%20schema%3D%5B%22State%22%2C%20%22LDS%20Type%22%2C%20%22Brand%22%2C%20%22Visits%22%5D%2C%20orient%3D%22row%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.group_by(%5B%22State%22%2C%20%22LDS%20Type%22%2C%20%22Brand%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.agg(pl.sum(%22Visits%22).alias(%22Total%20Visits%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.sort(by%3D%5B%22State%22%2C%20%22LDS%20Type%22%2C%20%22Total%20Visits%22%5D%2C%20descending%3D%5BFalse%2C%20False%2C%20True%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20top10_q4%20%3D%20q4.group_by(%5B%22State%22%2C%20%22LDS%20Type%22%5D).head(10)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fig4%20%3D%20px.scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20top10_q4.to_pandas()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22Total%20Visits%22%2C%20y%3D%22Brand%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22LDS%20Type%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20facet_col%3D%22State%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20size%3D%22Total%20Visits%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Q4%3A%20Top%20Same-Day%20Brands%20%E2%80%94%20LDS%20Temple%20%2F%20Seminary%20%2F%20Meetinghouse%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.ui.plotly(fig4)%0A%20%20%20%20return%20df_q1%2C%20fig%2C%20fig2%2C%20fig3%2C%20fig4%2C%20q2%2C%20q3%2C%20q4%0A%0A%0A%40app.cell%0Adef%20_(df_q1%2C%20mo)%3A%0A%20%20%20%20mo.ui.table(df_q1.head())%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fig%2C%20go%2C%20mo)%3A%0A%20%20%20%20q1_dash%20%3D%20go.Figure(fig)%20%20%20%20%20%0A%20%20%20%20q1_dash.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Q1%3A%20iOS%20vs%20Android%20Visit%20Share%20(LDS%20vs%20Other%20Churches)%22%2C%0A%20%20%20%20%20%20%20%20height%3D600%2C%20width%3D900%0A%20%20%20%20)%0A%20%20%20%20mo.ui.plotly(q1_dash)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22In%20Utah%2C%20iOS%20and%20Android%20visit%20shares%20are%20almost%20evenly%20split%20for%20both%20LDS%20and%20other%20churches.%20In%20Georgia%2C%20LDS%20visitors%20show%20a%20stronger%20tilt%20toward%20one%20platform%20(likely%20iOS)%20compared%20to%20Android%2C%20and%20other%20churches%20show%20a%20moderate%20difference.%20Overall%2C%20the%20data%20suggests%20platform%20preferences%20are%20balanced%20in%20Utah%20but%20diverge%20more%20in%20Georgia.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fig2%2C%20go%2C%20mo)%3A%0A%20%20%20%20q2_dash%20%3D%20go.Figure(fig2)%0A%20%20%20%20q2_dash.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Q2%3A%20Hourly%20Visit%20Patterns%20(LDS%20vs%20Other%20Churches)%22%2C%0A%20%20%20%20%20%20%20%20height%3D600%2C%20width%3D900%0A%20%20%20%20)%0A%20%20%20%20mo.ui.plotly(q2_dash)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20q2)%3A%0A%20%20%20%20mo.ui.table(q2.head())%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22In%20Georgia%2C%20most%20weighted%20church%20visits%20happen%20in%20the%20morning%20(around%209%E2%80%9311%20AM)%20for%20other%20churches%2C%20with%20a%20smaller%20evening%20rise%3B%20LDS%20activity%20there%20is%20minimal.%20In%20Utah%2C%20LDS%20visits%20dominate%2C%20peaking%20late%20morning%20to%20midday%20and%20showing%20a%20smaller%20evening%20bump%2C%20while%20other%20churches%20remain%20much%20less%20visited.%20The%20timing%20suggests%20traditional%20Sunday%20services%20drive%20GA%20traffic%2C%20while%20LDS%20activity%20in%20UT%20extends%20later%20into%20midday%20and%20includes%20evening%20events.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20q3)%3A%0A%20%20%20%20mo.ui.table(q3.head())%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fig3%2C%20go%2C%20mo)%3A%0A%20%20%20%20q3_dash%20%3D%20go.Figure(fig3)%0A%20%20%20%20q3_dash.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Q3%3A%20Top%20Same-Day%20Brands%20%E2%80%94%20LDS%20vs%20Other%20Churches%22%2C%0A%20%20%20%20%20%20%20%20height%3D600%2C%20width%3D900%0A%20%20%20%20)%0A%20%20%20%20mo.ui.plotly(q3_dash)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22In%20Georgia%2C%20people%20attending%20other%20churches%20are%20the%20main%20drivers%20of%20same-day%20brand%20visits%2C%20especially%20to%20big-box%20retailers%20(Walmart)%2C%20fast%20food%20(McDonald%E2%80%99s%2C%20Chick-fil-A)%2C%20and%20gas%2Fconvenience%20stores.%20LDS%20activity%20there%20is%20minimal.%20In%20Utah%2C%20the%20pattern%20reverses%3A%20LDS%20attendees%20dominate%20(less-leading%20margins)%20same-day%20brand%20visits%20--%20again%20favoring%20Walmart%20and%20McDonald%E2%80%99s%20--%20while%20other%20churches%20contribute%20only%20a%20small%20fraction.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20q4)%3A%0A%20%20%20%20mo.ui.table(q4.head())%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fig4%2C%20go%2C%20mo)%3A%0A%20%20%20%20q4_dash%20%3D%20go.Figure(fig4)%0A%20%20%20%20q4_dash.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Q4%3A%20Top%20Same-Day%20Brands%20%E2%80%94%20LDS%20Temple%20%2F%20Seminary%20%2F%20Meetinghouse%22%2C%0A%20%20%20%20%20%20%20%20height%3D600%2C%20width%3D900%0A%20%20%20%20)%0A%20%20%20%20mo.ui.plotly(q4_dash)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22In%20Georgia%2C%20LDS%20temple%20and%20meetinghouse%20visitors%20make%20relatively%20few%20same-day%20brand%20stops%2C%20with%20only%20small%20counts%20at%20gas%20stations%2C%20hotels%2C%20and%20fitness%20centers.%20In%20Utah%2C%20LDS%20Meetinghouse%20attendees%20drive%20most%20same-day%20brand%20visits%20--%20especially%20to%20fast%20food%20and%20grocery%20stores%20--%20while%20temple%20and%20seminary%20visits%20generate%20far%20less%20commercial%20spillover%20in%20Georgia%2C%20but%20in%20Utah%20has%20a%20way%20higher%20spillover%20than%20LDS%20Meetinghouses.%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
a4107adb705b916187250208c6981693f40b7633d16cb22f1b847723cc354481