Walgreens and Rite Aid are closing many stores, leaving pharmacy deserts in their wake.
Earlier this year, I tried to help any data journalists out there keep track of the closings. The Walgreens project and Rite Aid project have code for grabbing the current list of stores with their location data, and an data from initial run of the code.
These should provide a solid base for folks to work from and help us understand where the greatest impacts will be felt.
Data Tools Used
R
Rust
Go
Mapping Tools Used
Observable Plot
Today’s Entry Notes
I’m using Quarto, and the latest Observable Plot enhancements have not made it to there, yet, so my plan to use the Pointer transform to show popups on hover for each state was not possible.
While Observable Plot most certainly supports faceting, it was easier to just make the function, below, vs. try to fiddle with the positioning.
By using the className option for Plot.plot(), we get the ability to style the plot a bit more using CSS (like I did for these), or target the selector for futher manipulation with javascript.
It also turned out to be quicker to return a <div> wth the logo and plot in it than to fiddle with Plot.image(). I ended up having to convert the Walgreens official logo to an SVG from EPS and hand-editing the Rite Aid logo to remove the width and height attributes so it woul scale with the container.
This was also good practice in creating a parameterized function wrapper for Plot.
Code
functionstorePlot(opts) {const plt = Plot.plot({className: opts.class,caption: opts.caption,width: width,height: width * (3/4),style: {backgroundColor:"transparent", },projection:"albers-usa",marks: [ Plot.geo(nation, {strokeWidth:1.5,stroke:"#fff",strokeOpacity:1/10,fill:"#111", }), Plot.geo(statemesh, {strokeWidth:0.25,strokeOpacity:1/5, }), Plot.geo(nation, {stroke:"#999", }), Plot.dot( stores.filter((d) => d.chain== opts.chain), {x:"longitude",y:"latitude",fill: opts.color,fillOpacity:3/4,stroke:"#00000000",r:0.5, } ), ],});returnhtml`<div style="position: relative;">${plt} <img style="position: absolute; top: ${opts.top}; right: ${opts.right};" width="${opts.width}" src="${opts.logo}" /> </div> `;}// This is a geojson file we'll see quite a bit of this monthus =FileAttachment("static/data/us-counties-10m.json").json();// taking various subsets to plot as different layersstatemesh = topojson.mesh(us, us.objects.states);states = topojson.feature(us, us.objects.states).features;nation = topojson.feature(us, us.objects.nation);// our store datastores =FileAttachment("./static/data/2023-11-01.json").json();walgreensRed ="#E31836";riteAidGreen ="#99c45a";walgrens =storePlot({chain:"Walgreens",class:"walgreens",caption:"All U.S. Walgreens stores as of 2023-11-01",color: walgreensRed,logo:"static/walgreens-logo.svg",width:"50%",top:"0%",right:"10%",});riteAid =storePlot({chain:"Rite Aid",class:"rite-aid",caption:"All U.S. Rite Aid stores as of 2023-11-01",color: riteAidGreen,logo:"static/rite-aid-logo.svg",width:"25%",top:"4%",right:"10%",});
# Day 1: Points {.unnumbered}<style>svg.walgreens,svg.rite-aid {filter: drop-shadow(3px5px2pxrgb(000 / 0.4));}</style>### Pharmacy Deserts Basemaps & DataWalgreens and Rite Aid are closing many stores, leaving [pharmacy deserts](https://www.washingtonpost.com/business/2023/10/22/drugstore-close-pharmacy-deserts/) in their wake.Earlier this year, I tried to help any data journalists out there keep track of the closings. The [Walgreens project](https://gitlab.com/hrbrmstr/walgreens-api/-/tree/main) and [Rite Aid project](https://gitlab.com/hrbrmstr/rite-aid) have code for grabbing the current list of stores with their location data, and an data from initial run of the code.These should provide a solid base for folks to work from and help us understand where the greatest impacts will be felt.### Data Tools Used- R- Rust- Go### Mapping Tools Used- Observable Plot### Today's Entry NotesI'm using Quarto, and the latest Observable Plot enhancements have not made it to there, yet, so my plan to use the [`Pointer` transform](https://observablehq.com/plot/interactions/pointer#pointer-transform) to show popups on hover for each state was not possible.While Observable Plot most certainly supports [faceting](https://observablehq.com/plot/interactions/pointer#pointer-transform), it was easier to just make the function, below, vs. try to fiddle with the positioning.By using the `className` option for `Plot.plot()`, we get the ability to style the plot a bit more using CSS (like I did for these), or target the selector for futher manipulation with javascript.It also turned out to be quicker to return a `<div>` wth the logo and plot in it than to fiddle with `Plot.image()`. I ended up having to convert the Walgreens official logo to an SVG from EPS and hand-editing the Rite Aid logo to remove the `width` and `height` attributes so it woul scale with the container.This was also good practice in creating a parameterized function wrapper for `Plot`.```{ojs}function storePlot(opts) { const plt = Plot.plot({ className: opts.class, caption: opts.caption, width: width, height: width * (3 / 4), style: { backgroundColor: "transparent", }, projection: "albers-usa", marks: [ Plot.geo(nation, { strokeWidth: 1.5, stroke: "#fff", strokeOpacity: 1 / 10, fill: "#111", }), Plot.geo(statemesh, { strokeWidth: 0.25, strokeOpacity: 1 / 5, }), Plot.geo(nation, { stroke: "#999", }), Plot.dot( stores.filter((d) => d.chain == opts.chain), { x: "longitude", y: "latitude", fill: opts.color, fillOpacity: 3 / 4, stroke: "#00000000", r: 0.5, } ), ],}); return html`<div style="position: relative;"> ${plt} <img style="position: absolute; top: ${opts.top}; right: ${opts.right};" width="${opts.width}" src="${opts.logo}" /> </div> `;}// This is a geojson file we'll see quite a bit of this monthus = FileAttachment("static/data/us-counties-10m.json").json();// taking various subsets to plot as different layersstatemesh = topojson.mesh(us, us.objects.states);states = topojson.feature(us, us.objects.states).features;nation = topojson.feature(us, us.objects.nation);// our store datastores = FileAttachment("./static/data/2023-11-01.json").json();walgreensRed = "#E31836";riteAidGreen = "#99c45a";walgrens = storePlot({ chain: "Walgreens", class: "walgreens", caption: "All U.S. Walgreens stores as of 2023-11-01", color: walgreensRed, logo: "static/walgreens-logo.svg", width: "50%", top: "0%", right: "10%",});riteAid = storePlot({ chain: "Rite Aid", class: "rite-aid", caption: "All U.S. Rite Aid stores as of 2023-11-01", color: riteAidGreen, logo: "static/rite-aid-logo.svg", width: "25%", top: "4%", right: "10%",});```