|
| 1 | +--- |
| 2 | +author: [ezmiller] |
| 3 | +description: Getting to know our host city for Clojure/conj 2025. We dive into 311 service data to see what's on the minds of Charlotte's citizens and get a taste of our hands-on data analysis workshop. |
| 4 | +type: post |
| 5 | +date: '2025-08-15' |
| 6 | +category: conj |
| 7 | +tags: [clay, workflow, conj] |
| 8 | +draft: true |
| 9 | +format: |
| 10 | + html: {title: 'What''s the Buzz in Charlotte? A Pre-Conj Data Dive'} |
| 11 | + |
| 12 | +--- |
| 13 | +<style></style><style>.printedClojure .sourceCode { |
| 14 | + background-color: transparent; |
| 15 | + border-style: none; |
| 16 | +} |
| 17 | +</style><style>.clay-limit-image-width .clay-image {max-width: 100%} |
| 18 | +.clay-side-by-side .sourceCode {margin: 0} |
| 19 | +.clay-side-by-side {margin: 1em 0} |
| 20 | +</style> |
| 21 | +<script src="buzz_files/md-default0.js" type="text/javascript"></script><script src="buzz_files/md-default1.js" type="text/javascript"></script><script src="buzz_files/plotly2.js" type="text/javascript"></script> |
| 22 | +This November 12th, Clojure enthusiasts will gather in **Charlotte, North Carolina** |
| 23 | +for Clojure/conj 2025. |
| 24 | +For many of us, it's a cherished yearly tradition of code, |
| 25 | +conversations, and that special *"this is my people"* feeling. |
| 26 | + |
| 27 | +::: {.callout-note} |
| 28 | +Fun fact: during the Revolutionary War, a British general called Charlotte a "hornet's nest of rebellion" |
| 29 | +for its fierce resistance. |
| 30 | +That same spirit of passionate engagement seems to live on in the city's civic life today, |
| 31 | +on display using the hornet as their city emblem. |
| 32 | +::: |
| 33 | + |
| 34 | +In the spirit of exploration that defines our community, let's get to know our host city |
| 35 | +before we even arrive. |
| 36 | +What can 3 million service requests tell us about the heart of Charlotte? |
| 37 | + |
| 38 | + |
| 39 | +## A Glimpse into Charlotte's Data |
| 40 | + |
| 41 | +Let's find out by diving into the city's 311 system, which captures the pulse |
| 42 | +of city life through non-emergency service requests. |
| 43 | +Every pothole report, noise complaint, and fallen tree notification tells a story. |
| 44 | + |
| 45 | +Downloaded from [Charlotte Service Requests](https://data.charlottenc.gov/datasets/charlotte::service-requests-311/explore?location=35.265099%2C-80.810750%2C9.72). |
| 46 | + |
| 47 | + |
| 48 | +::: {.sourceClojure} |
| 49 | +```clojure |
| 50 | +(defonce Charlotte-311 |
| 51 | + (tc/dataset (fs/file (fs/home) "Downloads" "Service_Requests_311.csv") |
| 52 | + {:key-fn csk/->kebab-case-keyword})) |
| 53 | +``` |
| 54 | +::: |
| 55 | + |
| 56 | + |
| 57 | +Let's see what columns we have |
| 58 | + |
| 59 | + |
| 60 | +::: {.sourceClojure} |
| 61 | +```clojure |
| 62 | +(tc/column-names Charlotte-311) |
| 63 | +``` |
| 64 | +::: |
| 65 | + |
| 66 | + |
| 67 | + |
| 68 | +::: {.printedClojure} |
| 69 | +```clojure |
| 70 | +(:x |
| 71 | + :y |
| 72 | + :objectid |
| 73 | + :department |
| 74 | + :division |
| 75 | + :request-no |
| 76 | + :fiscal-year |
| 77 | + :fiscal-month |
| 78 | + :request-type |
| 79 | + :received-date |
| 80 | + :internal-field-observation |
| 81 | + :title |
| 82 | + :cmpd-division |
| 83 | + :neighborhood-profile-area |
| 84 | + :block-no |
| 85 | + :street-direction |
| 86 | + :street-name |
| 87 | + :street-type |
| 88 | + :city |
| 89 | + :state |
| 90 | + :zip-code |
| 91 | + :full-address |
| 92 | + :x-coord |
| 93 | + :y-coord |
| 94 | + :latitude |
| 95 | + :longitude |
| 96 | + :council-district |
| 97 | + :global-id |
| 98 | + :pid) |
| 99 | + |
| 100 | +``` |
| 101 | +::: |
| 102 | + |
| 103 | + |
| 104 | +I wonder what the request types are |
| 105 | + |
| 106 | + |
| 107 | +::: {.sourceClojure} |
| 108 | +```clojure |
| 109 | +(tc/group-by Charlotte-311 :request-type) |
| 110 | +``` |
| 111 | +::: |
| 112 | + |
| 113 | + |
| 114 | +::: {.clay-dataset} |
| 115 | +_unnamed [175 3]: |
| 116 | + |
| 117 | +| :name | :group-id | :data | |
| 118 | +|---------------------------|----------:|-----------------------------------------------| |
| 119 | +| MISSED RECYCLING | 0 | Group: MISSED RECYCLING [56694 29]: | |
| 120 | +| CDOT STREET SIGN REP/REPL | 1 | Group: CDOT STREET SIGN REP/REPL [14259 29]: | |
| 121 | +| STREET SWEEPING/FLUSHING | 2 | Group: STREET SWEEPING/FLUSHING [10876 29]: | |
| 122 | +| NON_RECYCLABLE ITEMS | 3 | Group: NON_RECYCLABLE ITEMS [1542623 29]: | |
| 123 | +| HNS HEALTH AND SANITATION | 4 | Group: HNS HEALTH AND SANITATION [147023 29]: | |
| 124 | +| CART REPAIR-GARBAGE | 5 | Group: CART REPAIR-GARBAGE [69893 29]: | |
| 125 | +| RECYCLABLE ITEMS | 6 | Group: RECYCLABLE ITEMS [366433 29]: | |
| 126 | +| SW DOCUMENT RECYCLING | 7 | Group: SW DOCUMENT RECYCLING [32594 29]: | |
| 127 | +| PARKING ON LAWN OFFHOURS | 8 | Group: PARKING ON LAWN OFFHOURS [6019 29]: | |
| 128 | +| CDOT SIGHT OBSTRUCTION | 9 | Group: CDOT SIGHT OBSTRUCTION [4055 29]: | |
| 129 | +| ... | ... | ... | |
| 130 | +| NEW SVC BUSINESS GARBAGE | 164 | Group: NEW SVC BUSINESS GARBAGE [225 29]: | |
| 131 | +| CURBIT PICKUP DAY INQUIRY | 165 | Group: CURBIT PICKUP DAY INQUIRY [39 29]: | |
| 132 | +| ROW OBSTRUCT OTHER | 166 | Group: ROW OBSTRUCT OTHER [1630 29]: | |
| 133 | +| SWS MLTFMLY SITE INVSTGT | 167 | Group: SWS MLTFMLY SITE INVSTGT [5 29]: | |
| 134 | +| ILLEGAL PARKING | 168 | Group: ILLEGAL PARKING [1211 29]: | |
| 135 | +| ZON DUPLEX/DUPLEXES | 169 | Group: ZON DUPLEX/DUPLEXES [68 29]: | |
| 136 | +| SUBDIVISIONS | 170 | Group: SUBDIVISIONS [29 29]: | |
| 137 | +| UT/WATER QUALITY TESTING | 171 | Group: UT/WATER QUALITY TESTING [1 29]: | |
| 138 | +| CART PURCHASE | 172 | Group: CART PURCHASE [8 29]: | |
| 139 | +| HOMELESS SUPPORT OUTREACH | 173 | Group: HOMELESS SUPPORT OUTREACH [929 29]: | |
| 140 | +| HNS ESCALATED REQUESTS | 174 | Group: HNS ESCALATED REQUESTS [82 29]: | |
| 141 | + |
| 142 | + |
| 143 | +::: |
| 144 | + |
| 145 | + |
| 146 | +Let's see what are the most common requests |
| 147 | + |
| 148 | + |
| 149 | +::: {.sourceClojure} |
| 150 | +```clojure |
| 151 | +(def frequent-requests |
| 152 | + (-> Charlotte-311 |
| 153 | + (tc/group-by :request-type) |
| 154 | + (tc/aggregate {:frequency tc/row-count}) |
| 155 | + (tc/order-by :frequency :desc))) |
| 156 | +``` |
| 157 | +::: |
| 158 | + |
| 159 | + |
| 160 | + |
| 161 | +::: {.sourceClojure} |
| 162 | +```clojure |
| 163 | +frequent-requests |
| 164 | +``` |
| 165 | +::: |
| 166 | + |
| 167 | + |
| 168 | +::: {.clay-dataset} |
| 169 | +_unnamed [175 2]: |
| 170 | + |
| 171 | +| :$group-name | :frequency | |
| 172 | +|---------------------------|-----------:| |
| 173 | +| NON_RECYCLABLE ITEMS | 1542623 | |
| 174 | +| RECYCLABLE ITEMS | 366433 | |
| 175 | +| HNS HEALTH AND SANITATION | 147023 | |
| 176 | +| CART REPAIR-GARBAGE | 69893 | |
| 177 | +| MISSED RECYCLING | 56694 | |
| 178 | +| 311 DOCUMENT | 52972 | |
| 179 | +| SW DOCUMENT GARBAGE | 46761 | |
| 180 | +| SW DOCUMENT RECYCLING | 32594 | |
| 181 | +| DEAD ANIMAL COLLECTION | 30048 | |
| 182 | +| SW DOCUMENT YARD WASTE | 26465 | |
| 183 | +| ... | ... | |
| 184 | +| COVID 19-PRICE GOUGING | 4 | |
| 185 | +| SW EXCESSIVE STORM-SW USE | 2 | |
| 186 | +| SW REMINDER BULKY-SW USE | 2 | |
| 187 | +| SWS MLTFMLY FIELD OBSERVE | 2 | |
| 188 | +| ON CALL - SWS SPEC SERV | 1 | |
| 189 | +| COMPLEX PROBLEM | 1 | |
| 190 | +| UT/LANDSCAPE | 1 | |
| 191 | +| DISABILITY ACT | 1 | |
| 192 | +| UT/MANDATORY | 1 | |
| 193 | +| BUS STOP-REMOVE TRASH CAN | 1 | |
| 194 | +| UT/WATER QUALITY TESTING | 1 | |
| 195 | + |
| 196 | + |
| 197 | +::: |
| 198 | + |
| 199 | + |
| 200 | +The most frequent request type is about non-recyclable items. |
| 201 | +It suggests Charlotte residents care about recycling |
| 202 | +but might need clearer guidelines about what can be recycled. |
| 203 | +The high volume of requests also shows that people feel comfortable |
| 204 | +asking the city for guidance. |
| 205 | +Data like this helps cities improve their communication and services. |
| 206 | + |
| 207 | + |
| 208 | +::: {.sourceClojure} |
| 209 | +```clojure |
| 210 | +(-> frequent-requests |
| 211 | + (plotly/base {:=title "Charlotte 311 Service Requests"}) |
| 212 | + (plotly/layer-bar {:=x-title "Request Type" |
| 213 | + :=y :frequency |
| 214 | + :=y-title "Count"})) |
| 215 | +``` |
| 216 | +::: |
| 217 | + |
| 218 | + |
| 219 | + |
| 220 | +```{=html} |
| 221 | +<div style="height:auto;width:100%;"><script>Plotly.newPlot(document.currentScript.parentElement, |
| 222 | + [{"y":[1542623,366433,147023,69893,56694,52972,46761,32594,30048,26465,25145,24900,24268,23914,20396,20359,20121,18946,17301,16702,16495,16012,15404,14337,14259,13106,12496,10876,10659,10616,10461,9922,9117,8710,8601,8286,8255,8243,8128,8057,7749,7528,7266,7264,6936,6355,6249,6019,5467,5301,5124,4967,4879,4431,4355,4055,3939,3836,3723,3559,3480,3248,3200,3003,2957,2823,2700,2663,2592,2592,2518,2392,2321,2187,2175,1874,1643,1630,1598,1440,1431,1365,1335,1325,1248,1211,1136,1045,1043,1001,983,977,971,969,929,870,836,835,816,794,790,785,785,677,564,509,478,476,441,406,368,364,351,331,278,264,250,228,225,219,214,210,208,185,180,151,128,125,113,105,100,89,82,74,68,63,61,60,53,51,43,41,39,37,33,29,28,28,27,22,18,15,15,15,12,11,10,9,9,8,8,6,5,4,4,2,2,2,1,1,1,1,1,1,1],"r":null,"name":"","fill":null,"mode":null,"width":null,"type":"bar","theta":null,"z":null,"lon":null,"lat":null,"text":null}], {"width":500,"height":400,"margin":{"t":25},"automargin":false,"plot_bgcolor":"rgb(235,235,235)","xaxis":{"gridcolor":"rgb(255,255,255)","title":"Request Type","showgrid":true},"yaxis":{"gridcolor":"rgb(255,255,255)","title":"Count","showgrid":true},"title":"Charlotte 311 Service Requests"}, {});</script></div> |
| 223 | +``` |
| 224 | + |
| 225 | + |
| 226 | +That's a long tail you have there. |
| 227 | +Let's focus on the top 5. |
| 228 | + |
| 229 | + |
| 230 | +::: {.sourceClojure} |
| 231 | +```clojure |
| 232 | +(-> frequent-requests |
| 233 | + (tc/select-rows (range 5)) |
| 234 | + (plotly/base {:=title "Charlotte 311 Service Requests"}) |
| 235 | + (plotly/layer-bar {:=x :$group-name |
| 236 | + :=x-title "Request Type" |
| 237 | + :=y :frequency |
| 238 | + :=y-title "Count"})) |
| 239 | +``` |
| 240 | +::: |
| 241 | + |
| 242 | + |
| 243 | + |
| 244 | +```{=html} |
| 245 | +<div style="height:auto;width:100%;"><script>Plotly.newPlot(document.currentScript.parentElement, |
| 246 | + [{"y":[1542623,366433,147023,69893,56694],"r":null,"name":"","fill":null,"mode":null,"width":null,"type":"bar","theta":null,"z":null,"lon":null,"lat":null,"x":["NON_RECYCLABLE ITEMS","RECYCLABLE ITEMS","HNS HEALTH AND SANITATION","CART REPAIR-GARBAGE","MISSED RECYCLING"],"text":null}], {"width":500,"height":400,"margin":{"t":25},"automargin":false,"plot_bgcolor":"rgb(235,235,235)","xaxis":{"gridcolor":"rgb(255,255,255)","title":"Request Type","showgrid":true},"yaxis":{"gridcolor":"rgb(255,255,255)","title":"Count","showgrid":true},"title":"Charlotte 311 Service Requests"}, {});</script></div> |
| 247 | +``` |
| 248 | + |
| 249 | + |
| 250 | +This brief analysis gives us a snapshot of daily life in Charlotte, revealing a community |
| 251 | +that's actively engaged in civic life and recycling. It's a perfect backdrop for the |
| 252 | +kind of thoughtful problem-solving we cherish in the Clojure community. |
| 253 | + |
| 254 | + |
| 255 | + |
| 256 | + |
| 257 | +## Join Us at the Workshop |
| 258 | + |
| 259 | +This journey from a raw CSV file to a clear visualization is exactly what our |
| 260 | +**Empowering Data Analysis through SciCloj** [workshop](https://www.2025.clojure-conj.org/workshops) is all about. |
| 261 | +Led by me, Ethan Miller, you'll start your Conj experience by diving into practical, |
| 262 | +hands-on data analysis and come away with new ideas to carry back home. |
| 263 | + |
| 264 | +**You will learn how to:** |
| 265 | + |
| 266 | +- Load and explore real-world datasets |
| 267 | +- Create clear, reproducible analyses |
| 268 | +- Share your insights through interactive notebooks |
| 269 | +- Leverage Clojure's immutable data structures for data science |
| 270 | + |
| 271 | +We can't wait to explore data with you. See you in Charlotte! |
| 272 | + |
| 273 | + |
| 274 | +```{=html} |
| 275 | +<div style="background-color:grey;height:2px;width:100%;"></div> |
| 276 | +``` |
| 277 | + |
| 278 | + |
| 279 | + |
| 280 | +```{=html} |
| 281 | +<div><pre><small><small>source: <a href="https://github.com/ClojureCivitas/clojurecivitas.github.io/blob/main/src/conferences/conj2025/workshop/scicloj/buzz.clj">src/conferences/conj2025/workshop/scicloj/buzz.clj</a></small></small></pre></div> |
| 282 | +``` |
0 commit comments