Which counties have gained the most population between 2020 and 2024? Which ones shrunk?
The US Census Bureau recently released the latest population estimates. The estimates are available at the national, state, county, and local level. In this post, we’ll take a quick look at which Wisconsin counties had the largest population gains and which ones shrunk.
Looking just at the two most most recent years, Dane County saw the largest absolute and relative increase in population: From 2023 to 2024, the counties population grew by 1.5%, or over 8,600 people. The only other county with a 1.5% population was Menominee. But Menominee is Wisconsin least populous county, and so a 1.5% increase is just 65 people! For absolute increases, Waukesha and Milwaukee counties come in second and third. Especially for Milwaukee County this is an exciting turnaround, after many years of losing population.
Fourteen of the Wisconsin’s 72 counties saw their populations shrink, but the losses were modest: Adams County saw the highest absolute and relative loses, with -0.8%, or 176 fewer people living in the county.
library(tidycensus)
library(tidyverse)
library(tmap)
library(sf)
library(gt)
wi_pop_2024 <- get_estimates(geography = "county",
variables = "POPESTIMATE",
state = "WI",
geometry = TRUE,
vintage = 2024,
year = 2024)
wi_pop_2023 <- get_estimates(geography = "county",
variables = "POPESTIMATE",
state = "WI",
geometry = TRUE,
vintage = 2024,
year = 2023)
wi_pop_23_24 <- rbind(wi_pop_2023, wi_pop_2024)
wi_pop_23_24 <- wi_pop_23_24 |>
st_drop_geometry() |>
pivot_wider(names_from = "year", values_from = "value",
names_prefix = "pop_",
id_cols = "NAME")
q <- wi_pop_2024 |>
select(NAME, geometry) |>
left_join(wi_pop_23_24, by = "NAME") |>
mutate(pop_change_abs = pop_2024 - pop_2023,
pop_change_pct = (pop_2024 - pop_2023)/pop_2023) |>
tm_shape() +
tm_polygons(fill = "pop_change_abs",
fill.scale = tm_scale_intervals(
n = 5,
style = "pretty"
),
fill.legend = tm_legend(
title = "Population change",
position = c("top", "right"))) +
tm_title(" ") +
tm_credits("Data: US Census Bureau Population Estimates\nVisualization: Harald Kliems",
position = c("RIGHT", "BOTTOM"),
just = "right")
p <- wi_pop_2024 |>
select(NAME, geometry) |>
left_join(wi_pop_23_24, by = "NAME") |>
mutate(pop_change_abs = pop_2024 - pop_2023) |>
mutate(pop_change_pct = round((pop_change_abs/pop_2023)*100, 1)) |>
tm_shape() +
tm_polygons(fill = "pop_change_pct",
fill.legend = tm_legend(
title = "relative change (%)",
position = c("top", "right")
))+
tm_title("Wisconsin 1-year county population change 2023-2024")
tmap_arrange(p,q)
If we compare the latest estimates compare with the 2020 estimates, the picture at the very top doesn’t change: Dane County again leads the pack, with a population growth of over 25,000 people, or 4.6%. For absolute growth, Waukesha County is second again, but its 2.3% relative growth doesn’t even get it into the top 10. Thirteen counties lost population since 2020, none more than Milwaukee County. Almost 14,000 fewer people, or 1.5% lived in the county compared to 2020. It will be interesting to see if the one-year turnaround from 2023 to 2024 signals a larger trend!
wi_pop_2020 <- get_estimates(geography = "county",
variables = "POPESTIMATE",
state = "WI",
geometry = TRUE,
vintage = 2024,
year = 2020)
wi_pop_20_24 <- rbind(wi_pop_2020, wi_pop_2024)
wi_pop_20_24 <- wi_pop_20_24 |>
st_drop_geometry() |>
pivot_wider(names_from = "year", values_from = "value",
names_prefix = "pop_",
id_cols = "NAME")
q <- wi_pop_2024 |>
select(NAME, geometry) |>
left_join(wi_pop_20_24, by = "NAME") |>
mutate(pop_change_abs = pop_2024 - pop_2020,
pop_change_pct = (pop_2024 - pop_2020)/pop_2020) |>
tm_shape() +
tm_polygons(fill = "pop_change_abs",
fill.legend = tm_legend(
title = "absolute change",
position = c("top", "right"))) +
tm_title(" ") +
tm_credits("Data: US Census Bureau Population Estimates\nVisualization: Harald Kliems",
position = c("RIGHT", "BOTTOM"),
just = "right")
p <- wi_pop_2024 |>
select(NAME, geometry) |>
left_join(wi_pop_20_24, by = "NAME") |>
mutate(pop_change_abs = pop_2024 - pop_2020) |>
mutate(pop_change_pct = round((pop_change_abs/pop_2020)*100, 1)) |>
tm_shape() +
tm_polygons(fill = "pop_change_pct",
fill.scale = tm_scale_intervals(
n = 6,
style = "pretty"
),
fill.legend = tm_legend(
title = "relative change (%)",
position = c("top", "right")
))+
tm_title("Wisconsin county population change 2020-2024")
tmap_arrange(p,q)
Here are all the numbers in a big table.
wi_pop_20_24 |>
left_join(wi_pop_23_24 |> select(NAME, pop_2023)) |>
mutate(NAME = str_remove(NAME, "County, Wisconsin"),
chg_20_24_abs = pop_2024 - pop_2020,
chg_20_24_pct = chg_20_24_abs / pop_2020,
chg_23_24_abs = pop_2024 - pop_2023,
chg_23_24_pct = chg_23_24_abs / pop_2023) |>
arrange(desc(chg_20_24_pct)) |>
gt() |>
data_color(
columns = c(chg_20_24_abs,
chg_20_24_pct,
chg_23_24_abs,
chg_23_24_pct),
method = "numeric",
palette = "BrBG"
) |>
cols_label(
NAME = "County",
pop_2020 = "2020",
pop_2023 = "2023",
pop_2024 = "2024",
chg_20_24_abs = "absolute",
chg_23_24_abs = "absolute",
chg_23_24_pct = "percent",
chg_20_24_pct = "percent"
) |>
tab_spanner(
label = "Population estimate",
columns = c(pop_2020, pop_2023, pop_2024)
) |>
tab_spanner(
label = "4-year change (2020-2024)",
columns = c(chg_20_24_abs, chg_20_24_pct)
) |>
tab_spanner(
label = "1-year change (2023-2024)",
columns = c(chg_23_24_abs, chg_23_24_pct)
) |>
fmt_percent(
columns = ends_with("_pct"),
scale_value = T, decimals = 1, force_sign = T
) |>
fmt_integer(
columns = c(
pop_2020,
pop_2023,
pop_2024,
chg_23_24_abs,
chg_20_24_abs
),
use_seps = T
) |>
tab_source_note(
source_note = md(
"Data: US Census Population Estimates, Vintage 2024"
)
)
County |
Population estimate
|
4-year change (2020-2024)
|
1-year change (2023-2024)
|
||||
---|---|---|---|---|---|---|---|
2020 | 2023 | 2024 | absolute | percent | absolute | percent | |
Dane | 562,620 | 579,739 | 588,347 | 25,727 | +4.6% | 8,608 | +1.5% |
St. Croix | 93,893 | 97,156 | 97,954 | 4,061 | +4.3% | 798 | +0.8% |
Lafayette | 16,604 | 17,059 | 17,306 | 702 | +4.2% | 247 | +1.4% |
Sawyer | 18,119 | 18,619 | 18,835 | 716 | +4.0% | 216 | +1.2% |
Bayfield | 16,238 | 16,809 | 16,838 | 600 | +3.7% | 29 | +0.2% |
Forest | 9,168 | 9,381 | 9,506 | 338 | +3.7% | 125 | +1.3% |
Vilas | 23,097 | 23,914 | 23,948 | 851 | +3.7% | 34 | +0.1% |
Burnett | 16,578 | 17,089 | 17,187 | 609 | +3.7% | 98 | +0.6% |
Adams | 20,682 | 21,528 | 21,352 | 670 | +3.2% | −176 | −0.8% |
Pepin | 7,343 | 7,482 | 7,555 | 212 | +2.9% | 73 | +1.0% |
Eau Claire | 105,877 | 108,058 | 108,830 | 2,953 | +2.8% | 772 | +0.7% |
Pierce | 42,229 | 43,101 | 43,380 | 1,151 | +2.7% | 279 | +0.6% |
Ozaukee | 91,627 | 93,520 | 93,956 | 2,329 | +2.5% | 436 | +0.5% |
Oconto | 39,077 | 39,741 | 40,037 | 960 | +2.5% | 296 | +0.7% |
Florence | 4,563 | 4,695 | 4,673 | 110 | +2.4% | −22 | −0.5% |
Waukesha | 407,518 | 414,013 | 417,029 | 9,511 | +2.3% | 3,016 | +0.7% |
Outagamie | 190,973 | 193,828 | 195,390 | 4,417 | +2.3% | 1,562 | +0.8% |
Portage | 70,412 | 71,461 | 72,040 | 1,628 | +2.3% | 579 | +0.8% |
Washburn | 16,623 | 16,996 | 16,982 | 359 | +2.2% | −14 | −0.1% |
Waushara | 24,550 | 25,014 | 25,079 | 529 | +2.2% | 65 | +0.3% |
Calumet | 52,478 | 53,303 | 53,602 | 1,124 | +2.1% | 299 | +0.6% |
Vernon | 30,710 | 31,143 | 31,351 | 641 | +2.1% | 208 | +0.7% |
Brown | 268,966 | 272,074 | 273,909 | 4,943 | +1.8% | 1,835 | +0.7% |
Green Lake | 19,027 | 19,417 | 19,370 | 343 | +1.8% | −47 | −0.2% |
Polk | 45,029 | 45,845 | 45,831 | 802 | +1.8% | −14 | −0.0% |
Iron | 6,140 | 6,277 | 6,235 | 95 | +1.5% | −42 | −0.7% |
Dunn | 45,453 | 45,827 | 46,135 | 682 | +1.5% | 308 | +0.7% |
Chippewa | 66,346 | 66,949 | 67,323 | 977 | +1.5% | 374 | +0.6% |
Washington | 136,811 | 138,496 | 138,727 | 1,916 | +1.4% | 231 | +0.2% |
Door | 30,119 | 30,566 | 30,512 | 393 | +1.3% | −54 | −0.2% |
Taylor | 19,938 | 20,123 | 20,167 | 229 | +1.1% | 44 | +0.2% |
Ashland | 16,015 | 16,103 | 16,196 | 181 | +1.1% | 93 | +0.6% |
Buffalo | 13,323 | 13,440 | 13,464 | 141 | +1.1% | 24 | +0.2% |
Marinette | 41,900 | 42,113 | 42,343 | 443 | +1.1% | 230 | +0.5% |
Sauk | 65,793 | 66,143 | 66,486 | 693 | +1.1% | 343 | +0.5% |
Shawano | 40,869 | 41,148 | 41,299 | 430 | +1.1% | 151 | +0.4% |
Marquette | 15,580 | 15,851 | 15,743 | 163 | +1.0% | −108 | −0.7% |
Rock | 163,761 | 164,443 | 165,461 | 1,700 | +1.0% | 1,018 | +0.6% |
Iowa | 23,718 | 23,881 | 23,963 | 245 | +1.0% | 82 | +0.3% |
Kewaunee | 20,563 | 20,733 | 20,751 | 188 | +0.9% | 18 | +0.1% |
Winnebago | 171,796 | 172,105 | 173,307 | 1,511 | +0.9% | 1,202 | +0.7% |
Oneida | 37,877 | 38,189 | 38,175 | 298 | +0.8% | −14 | −0.0% |
Marathon | 138,114 | 138,838 | 139,091 | 977 | +0.7% | 253 | +0.2% |
Walworth | 105,310 | 106,008 | 106,029 | 719 | +0.7% | 21 | +0.0% |
Grant | 51,979 | 51,894 | 52,330 | 351 | +0.7% | 436 | +0.8% |
Menominee | 4,258 | 4,221 | 4,286 | 28 | +0.7% | 65 | +1.5% |
Clark | 34,629 | 34,792 | 34,801 | 172 | +0.5% | 9 | +0.0% |
Green | 37,033 | 36,934 | 37,183 | 150 | +0.4% | 249 | +0.7% |
Price | 14,036 | 14,098 | 14,087 | 51 | +0.4% | −11 | −0.1% |
Langlade | 19,466 | 19,435 | 19,535 | 69 | +0.4% | 100 | +0.5% |
Racine | 198,065 | 197,407 | 198,651 | 586 | +0.3% | 1,244 | +0.6% |
Sheboygan | 118,058 | 117,995 | 118,331 | 273 | +0.2% | 336 | +0.3% |
Barron | 46,723 | 46,922 | 46,810 | 87 | +0.2% | −112 | −0.2% |
Monroe | 46,299 | 46,193 | 46,370 | 71 | +0.2% | 177 | +0.4% |
Manitowoc | 81,412 | 81,325 | 81,513 | 101 | +0.1% | 188 | +0.2% |
Lincoln | 28,429 | 28,430 | 28,461 | 32 | +0.1% | 31 | +0.1% |
Fond du Lac | 104,156 | 104,135 | 104,269 | 113 | +0.1% | 134 | +0.1% |
La Crosse | 120,943 | 120,717 | 121,060 | 117 | +0.1% | 343 | +0.3% |
Jefferson | 86,208 | 85,971 | 86,245 | 37 | +0.0% | 274 | +0.3% |
Trempealeau | 30,813 | 30,939 | 30,801 | −12 | −0.0% | −138 | −0.4% |
Rusk | 14,181 | 14,252 | 14,168 | −13 | −0.1% | −84 | −0.6% |
Douglas | 44,348 | 44,252 | 44,276 | −72 | −0.2% | 24 | +0.1% |
Kenosha | 169,202 | 167,867 | 168,754 | −448 | −0.3% | 887 | +0.5% |
Jackson | 21,095 | 20,938 | 21,027 | −68 | −0.3% | 89 | +0.4% |
Wood | 74,189 | 74,037 | 73,943 | −246 | −0.3% | −94 | −0.1% |
Crawford | 16,084 | 15,991 | 16,008 | −76 | −0.5% | 17 | +0.1% |
Columbia | 58,520 | 57,949 | 58,113 | −407 | −0.7% | 164 | +0.3% |
Juneau | 26,780 | 26,557 | 26,590 | −190 | −0.7% | 33 | +0.1% |
Dodge | 89,344 | 88,501 | 88,635 | −709 | −0.8% | 134 | +0.2% |
Richland | 17,283 | 17,251 | 17,123 | −160 | −0.9% | −128 | −0.7% |
Waupaca | 51,806 | 51,324 | 51,171 | −635 | −1.2% | −153 | −0.3% |
Milwaukee | 938,609 | 921,860 | 924,740 | −13,869 | −1.5% | 2,880 | +0.3% |
Data: US Census Population Estimates, Vintage 2024 |
For attribution, please cite this work as
Kliems (2025, May 20). Harald Kliems: County-level population change in Wisconsin. Retrieved from https://haraldkliems.netlify.app/posts/2025-05-20-wisconsin-county-population-change/
BibTeX citation
@misc{kliems2025county-level, author = {Kliems, Harald}, title = {Harald Kliems: County-level population change in Wisconsin}, url = {https://haraldkliems.netlify.app/posts/2025-05-20-wisconsin-county-population-change/}, year = {2025} }