TidyTuesday Week 14: Timely and Effective Care by US State
This week we’re exploring state-level results for medicare.gov ‘timely and effective care’ measurements. As of 2025-04-06, the data is available at the Centers for Medicare and Medicaid Services (CMS) website. Thanks to former TidyTuesday team member Tracy Teal (@tracykteal) for the dataset suggestion and the link to a visualization by Kayla Zhu and Christina Kostandi at the Visual Capitalist.
TidyTuesday
Data Visualization
R Programming
2025
Author
Peter Gray
Published
April 8, 2025
#### 1. Python code
Show code
import pandas as pdimport osimport geopandas as gpdfrom plotnine import ( ggplot, aes, coord_fixed, facet_wrap, geom_map, geom_polygon, geom_text, labs, scale_fill_brewer, scale_fill_continuous, scale_x_continuous, scale_y_continuous, scale_size_continuous, stage, coord_cartesian, element_line, element_rect, element_text, theme_void, theme,)from shapely.geometry import Polygon, MultiPolygonfrom plotnine import scale_fill_gradientpcare_state = pd.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2025/2025-04-08/care_state.csv')# Filter the data for Emergency Department and relevant statesexcluded_states = ["DC", "GU", "MH", "MP", "PR", "VI", "AS", "AL", "HI"]ed_data = pcare_state[ (pcare_state["condition"] =="Emergency Department") & (~pcare_state["state"].isin(excluded_states)) & (pcare_state["measure_id"] =="OP_22")]# Load state boundary shapefilestate_data = gpd.read_file("~/Documents/Coding/Website/data_visualisations/TidyTuesday/2025/maps/ne_110m_admin_1_states_provinces.shp")excluded_states = ["HI", "AK"] # Exclude Hawaii and Alaskastate_data = state_data[~state_data['postal'].isin(excluded_states)]state_data = state_data[state_data['admin'] =='United States of America']# Merge state boundaries with Emergency Department datastate_data['postal'] = state_data['postal'].str.upper()merged_data = state_data.merge(ed_data, left_on="postal", right_on="state", how="left")# Calculate the centroid of each state for text placementmerged_data['centroid'] = merged_data.geometry.centroidmerged_data['centroid_x'] = merged_data['centroid'].apply(lambda x: x.x)merged_data['centroid_y'] = merged_data['centroid'].apply(lambda x: x.y)# Explode multi-part geometries into individual rowsmerged_data = merged_data.explode(index_parts=False)# Extract polygon coordinatesdef get_coords(row):ifisinstance(row.geometry, Polygon): exterior = row.geometry.exterior.coordsreturnlist(exterior)elifisinstance(row.geometry, MultiPolygon):# Take only the largest polygon (simplification) largest_poly =max(row.geometry.geoms, key=lambda a: a.area)returnlist(largest_poly.exterior.coords)else:returnNonemerged_data["coords"] = merged_data.apply(get_coords, axis=1)merged_data = merged_data.explode("coords", ignore_index=True)# Create longitude and latitude columnsmerged_data["longitude"] = merged_data["coords"].apply(lambda x: x[0])merged_data["latitude"] = merged_data["coords"].apply(lambda x: x[1])merged_data["score_label"] = merged_data["score"].apply(lambda x: f"{round(x)}%"if pd.notnull(x) else"")# Now plotplot = ( ggplot(merged_data)+ geom_polygon( aes(x="longitude", y="latitude", group="postal", fill="score"), color="black" )+ geom_text( aes(x="centroid_x", y="centroid_y", label="score_label"), size=7, color="black" )+ scale_fill_gradient(name="Percent", low="#f1eef6", high="#045a8d")+ labs( title="Percentage of Patients Who Left the\nEmergency Department Before Being Seen" )+ coord_fixed()+ theme_void()+ theme( legend_position="bottom", legend_title=element_text(size=10, weight="bold"), legend_text=element_text(size=8), plot_title=element_text(size=14, weight="bold") ))