County-level population change in Wisconsin

Wisconsin population map

Which counties have gained the most population between 2020 and 2024? Which ones shrunk?


Author

Affiliation

Harald Kliems ORCID ID for Harald Kliems

 

Published

May 20, 2025

Citation

Kliems, 2025


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.

One-year change: 2023 to 2024

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.

Show code
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)
Show code
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)

Four-year change: 2024 to 2024

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!

Show code
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)
Show code
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.

Show code
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

Footnotes

    Citation

    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}
    }