# cow-tools: everything, in one file > Uruguay's livestock declarations and its whole open-data catalogue, as linked data for agents: an MCP endpoint, notebooks, a guide, and a personal agent to talk to. We can’t say either. But it is all here: every animal declared to DICOSE in 2024 and 2025, department by department, as linked data that remembers where each number came from; every dataset in Uruguay’s open-data catalogue, findable by what it means; and notebooks, notes and a personal agent to read them with. It is built for agents. People are welcome, and get the notebooks. ## The data ### Uruguay's livestock, 2024 and 2025 (`uruguay-cows`) The sworn livestock declarations (Declaración Jurada de Existencias) that Uruguay's Ministry of Livestock, Agriculture and Fisheries (MGAP) collects through DICOSE and publishes through SNIG, for the 2024 and 2025 declaration years. Each observation is a count of animals by department, enumeration area, species and category, kept as an RDF Data Cube with PROV-O provenance back to the published CSV and SKOS code lists for departments, species and categories. Curated cow_* tools answer herd sizes, rankings, comparisons and quality warnings exactly to source. - Size: 1,080,525 observations · 25,893,355 triples - Source: MGAP, DICOSE – SNIG: Declaración Jurada de Existencias 2024 and 2025 (Ministerio de Ganadería, Agricultura y Pesca (MGAP)): https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2024 , https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025 - Licence: Licencia de Datos Abiertos del Uruguay (https://www.gub.uy/agencia-gobierno-electronico-sociedad-informacion-conocimiento/sites/agencia-gobierno-electronico-sociedad-informacion-conocimiento/files/documentos/publicaciones/licencia_de_datos_abiertos_0.pdf) - Attribution: Fuente: MGAP – DICOSE/SNIG, Declaración Jurada de Existencias 2024 y 2025 (catalogodatos.gub.uy). Restructured as linked data by cow-tools; every number keeps its source. - Freshness: files retrieved 2026-07-05 · source updated 2026-06-10 (2024) and 2026-06-17 (2025) - Keywords: Uruguay, livestock, cattle, dairy, sheep, DICOSE, SNIG, MGAP, RDF Data Cube, PROV-O, departments ### Uruguay's open-data catalogue, all of it (`uruguay-catalogue`) A harvest of Uruguay's national open-data catalogue, catalogodatos.gub.uy (CKAN, DCAT): every dataset's title, description, publisher, licence, themes, update dates and download links, as a graph with a semantic index. An agent can ask for 'electricity consumption by department' and find the entries that hold it, then read their metadata and follow their links to the files. Each entry keeps the licence its publisher gave it. - Size: 2,718 datasets · 70 publishers · 258,246 triples (the whole catalogue on 2026-10-14) - Source: Catálogo Nacional de Datos Abiertos (catalogodatos.gub.uy) (AGESIC and the publishing agencies): https://catalogodatos.gub.uy/ - Licence: Each entry keeps its publisher's licence (most: Licencia de Datos Abiertos del Uruguay) (https://www.gub.uy/agencia-gobierno-electronico-sociedad-informacion-conocimiento/sites/agencia-gobierno-electronico-sociedad-informacion-conocimiento/files/documentos/publicaciones/licencia_de_datos_abiertos_0.pdf) - Attribution: Fuente: Catálogo Nacional de Datos Abiertos, catalogodatos.gub.uy; each dataset's publisher as named in its entry. - Freshness: harvested 2026-10-14 from the CKAN API · refreshed by re-running the harvest, not on a schedule - Keywords: Uruguay, open data, catalogue, DCAT, CKAN, datasets, semantic search, AGESIC ### The guide (`cow-tools-guide`) Curated documents about the data: one per department, a glossary of DICOSE terms (categories, species, declaration years), a reading path for newcomers, and a companion note for every notebook, with the caveats an analyst should know before trusting a number. Published as pages at /guide/, each with a markdown twin; agents also read it through the same MCP endpoint. - Size: 36 documents - Source: Written by Sophia from the two datasets above (Sophia Labs): https://cow-tools.sophia-labs.com/ - Licence: CC BY 4.0 (Sophia's guide documents and notebooks; the data keeps its own licence) (https://creativecommons.org/licenses/by/4.0/) - Attribution: cow-tools, Sophia Labs. - Freshness: last edited 2026-10-14 - Keywords: Uruguay, guide, glossary, departments, notebooks, DICOSE ## Connect your agent ### 1. Read: MCP, read-only, no account and no key `https://cow-tools.sophia-labs.com/mcp` (streamable HTTP, JSON-RPC 2.0). The tools are listed live by `tools/list`: the curated `cow_*` tools (herds by department, species, category and year; rankings; comparisons; quality warnings), SPARQL, semantic search and the guide's documents. - Claude Code: `claude mcp add --transport http cow-tools https://cow-tools.sophia-labs.com/mcp` - Claude Desktop, claude.ai, ChatGPT: add a custom connector with the URL above and no authentication. - Cursor (`~/.cursor/mcp.json`): `{"mcpServers": {"cow-tools": {"url": "https://cow-tools.sophia-labs.com/mcp"}}}` - Discovery: `https://cow-tools.sophia-labs.com/.well-known/ai-catalog.json` lists the MCP server card. ### 2. Talk: a personal agent of your own, over the ride protocol Create a session, prompt it, watch it answer, come back later. It runs on your OpenRouter key (header `X-Model-Key`) or on a Sophia account (header `Authorization: Bearer `; $0.50 of credit to start, cheap models). Never put a key in a URL. ```sh B=https://cow-tools.sophia-labs.com/services/vehicle/g/uruguay-cows H=(-H "X-Model-Key: $OPENROUTER_API_KEY" -H "x-vehicle-client-id: my-agent-1" -H "content-type: application/json") curl -s "$B/sessions" "${H[@]}" -d '{"requestId":"new-1","model":"openrouter/openai/gpt-6-luna"}' # → session.created, value.session.sessionId curl -s "$B/sessions/$SID/commands" "${H[@]}" -d '{"requestId":"q-1","op":"prompt","text":"How many dairy cows were declared in Florida in 2025?"}' curl -sN "$B/sessions/$SID/events?since=0" "${H[@]}" -H "accept: text/event-stream" # or ?since=0&waitMs=25000 (long-poll) ``` Or with `vehicle ride` (JSONL over stdio; https://github.com/sophia-labs/vehicle, MIT): ```sh cargo install --locked --git https://github.com/sophia-labs/vehicle # Rust 1.88+; on Linux also libssl-dev and pkg-config export VEHICLE_MODEL_KEY=sk-or-… # your OpenRouter key, read from the environment, never argv vehicle ride --gardend https://cow-tools.sophia-labs.com --graph uruguay-cows --new --client-id my-agent-1 # then one request per line: {"op":"prompt","requestId":"r1","text":"…"} and {"op":"watch","requestId":"w1","waitMs":30000} ``` The ride protocol (`sophia.vehicle-ride.v2`), under https://cow-tools.sophia-labs.com/services/vehicle/g/uruguay-cows: every answer is one frame, `{"protocol":"sophia.vehicle-ride.v2","type":…,"value":…}`, or an error frame with a `code` and a `message`. A `requestId` makes any request safe to repeat. `x-vehicle-client-id` names your client; one client drives a session at a time (the lease). - `POST /sessions` {requestId, model?, budget?}: a session; you hold its lease (`session.created`, `value.session.sessionId`) - `GET /sessions`: your sessions, newest first - `GET /sessions/`: the transcript, and the cursor to watch from - `POST /sessions//claim` {requestId}: drive it again after a while - `POST /sessions//commands` {requestId, op: prompt | follow_up | steer | abort | fork | clone, text?} - `GET /sessions//events?since=`: SSE with `accept: text/event-stream`, or `&waitMs=25000` to long-poll; events `command.delivered`, `message.delta` (text as it comes), `tool.started`, `tool.result`, `message.completed`, `budget.exceeded`, `run.settled` - `PATCH /sessions/` {title}, `DELETE /sessions/`: rename it, or put it away A session is yours: only you read it or drive it, and it waits for you. The whole protocol, every route, event and error code: https://cow-tools.sophia-labs.com/protocol/ride-v2.md (as a page: https://cow-tools.sophia-labs.com/protocol/index.html). ## Questions, with their exact answers - “How many dairy cows were declared in Florida in 2025?” → 100,116 dairy cows on dairy holdings (79,048 milking, 21,068 dry: DICOSE's PD+PF count); 103,472 counting every holding (PD+AD). (cow_herd (uruguay-cows), exact to the DICOSE 2025 CSV) - “Find a dataset about electricity consumption by department.” → None by department: no departmental electricity-consumption series is on the catalogue. The nearest it finds: MIEM's industrial energy consumption surveys (first) and MIDES's households lacking electricity, by department (fourth). (semantic search over uruguay-catalogue) - “Which department had the most sheep in 2024, and how many?” → Salto, with 1,151,124 sheep (then Artigas, 888,293). (cow_rank (uruguay-cows)) ## Notebooks ### The national herd at a glance Finding: Uruguay's holders declared 12,265,269 cattle on 30 June 2025 (11,583,321 beef and 681,948 dairy) and 4,799,066 sheep. On 2024, cattle changed +1.05% and sheep -11.47%. Page: https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/national-herd/national-herd.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/national-herd/index.md # The national herd at a glance **Answer.** Uruguay's holders declared **12,265,269 cattle** on 30 June 2025 (11,583,321 beef and 681,948 dairy) and **4,799,066 sheep**. On 2024, cattle changed +1.05% and sheep -11.47%. Notebook: https://cow-tools.sophia-labs.com/notebooks/national-herd/national-herd.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## Findings - Uruguay's holders declared **12,265,269 cattle** on 30 June 2025 (11,583,321 beef and 681,948 dairy) and **4,799,066 sheep**. On 2024, cattle changed +1.05% and sheep -11.47%. - **Florida** has the most cattle (1,117,097); Montevideo the fewest (2,736). The five largest departments hold 40.6% of the national herd. ## The notebook Every year each livestock holder in Uruguay files a sworn declaration with DICOSE (the Ministry of Livestock's control division) saying what animals are on their land on 30 June. SNIG publishes the aggregates on the national open-data catalogue, down to the *área de enumeración*, a census area a few hundred square kilometres across. cow-tools turns those CSVs into an RDF Data Cube with provenance, and this notebook asks the cube the first question anyone asks: **how many animals are there?** Every number below comes from a SPARQL query against the demo's own endpoint, and every headline number is checked against the original CSV, re-read from the bytes the cube was built from. If any check disagrees, this notebook stops; it never prints a number it could not reproduce. ```python # Setup: the client talks to https://cow-tools.sophia-labs.com unless # COWTOOLS_BASE_URL says otherwise. import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc print("endpoint:", cw.BASE_URL, "· graph:", cw.COWS) ``` ```text endpoint: http://127.0.0.1:7795 · graph: uruguay-cows ``` ## Animals by species The cube keeps one observation per row of `datosanimales.csv`: a species in a combination of department, census area, police section and a handful of producer classifications. Its `cow:animalsCount` is the column DICOSE has always used for stock, *propios dentro + ajenos dentro*: animals physically on the holding, whoever owns them. ```python # The query: sum the stock of every species, both years. species = cw.sparql(""" SELECT ?year ?species (SUM(?n) AS ?animals) (SUM(?h) AS ?holder_rows) (COUNT(?obs) AS ?observations) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year ?year ; cow:species ?species ; cow:animalsCount ?n . OPTIONAL { ?obs cow:holdersCount ?h } } } GROUP BY ?year ?species ORDER BY ?year ?species """) species["code"] = species["species"].str.rsplit("/", n=1).str[-1] species["label"] = species["code"].map(cw.SPECIES) cc.show_table(species[["year", "code", "label", "animals", "observations"]].astype({"year": str}), name="species") ``` | year | code | label | animals | observations | |-------:|-------:|:-----------------|:-----------|:---------------| | 2024 | 1 | BOVINOS | 11,449,817 | 27,508 | | 2024 | 11 | BOVINOS DE LECHE | 688,331 | 2,188 | | 2024 | 2 | OVINOS | 5,420,661 | 15,938 | | 2024 | 3 | YEGUARIZOS | 398,724 | 22,111 | | 2024 | 4 | CAPRINOS | 9,772 | 9,693 | | 2024 | 5 | SUINOS | 110,583 | 3,042 | | 2025 | 1 | BOVINOS | 11,583,321 | 27,151 | | 2025 | 11 | BOVINOS DE LECHE | 681,948 | 2,104 | | 2025 | 2 | OVINOS | 4,799,066 | 15,882 | | 2025 | 3 | YEGUARIZOS | 405,813 | 22,080 | | 2025 | 4 | CAPRINOS | 10,415 | 8,722 | | 2025 | 5 | SUINOS | 117,040 | 3,157 | Two species codes are cattle. DICOSE files dairy cattle (`11`, *bovinos de leche*) apart from beef cattle (`1`), so "how many cattle" means the sum of both. Sheep are `2`. ```python wide = species.pivot(index="code", columns="year", values="animals").fillna(0).astype(int) cattle = {y: int(wide.loc[cw.BEEF, y] + wide.loc[cw.DAIRY, y]) for y in (2024, 2025)} sheep = {y: int(wide.loc[cw.SHEEP, y]) for y in (2024, 2025)} cw.finding("headline", f"Uruguay's holders declared **{cattle[2025]:,} cattle** on 30 June 2025 " f"({int(wide.loc[cw.BEEF, 2025]):,} beef and {int(wide.loc[cw.DAIRY, 2025]):,} dairy) " f"and **{sheep[2025]:,} sheep**. On 2024, cattle changed {cattle[2025]/cattle[2024]-1:+.2%} " f"and sheep {sheep[2025]/sheep[2024]-1:+.2%}.") ``` > **Finding.** Uruguay's holders declared **12,265,269 cattle** on 30 June 2025 (11,583,321 beef and 681,948 dairy) and **4,799,066 sheep**. On 2024, cattle changed +1.05% and sheep -11.47%. ### Cross-check against the source The independent path: open the original `datosanimales.csv` for each year (verified byte for byte against the SHA-256 the cube recorded at ingest), sum the `AnimalesPorEspeciePD_AD` column with pandas, and demand equality to the head. Then compare with the figures the cow-tools WP-0 oracle fixed in July (12,138,148 and 12,265,269 cattle; 4,799,066 sheep in 2025). ```python for year in (2024, 2025): csv = cw.source_csv(year, "datosanimales.csv") stock = cw.num(csv["AnimalesPorEspeciePD_AD"]).groupby(csv["EspecieCodigo"]).sum() for code in wide.index: cw.check(f"{year} {cw.SPECIES[code].lower()}: cube = CSV", int(wide.loc[code, year]), int(stock.get(code, 0)), source=f"datosanimales.csv {year}, column AnimalesPorEspeciePD_AD") rows = len(csv) cw.check(f"{year}: one observation per CSV row", int(species.query("year == @year")["observations"].sum()), rows, source=f"datosanimales.csv {year} has {rows:,} data rows") cw.check("2024 cattle (WP-0 oracle)", cattle[2024], 12_138_148, source="cow-tools examples/wp0_oracle.rs (b)") cw.check("2025 cattle (WP-0 oracle)", cattle[2025], 12_265_269, source="cow-tools examples/wp0_oracle.rs (b)") cw.check("2025 sheep (WP-0 oracle)", sheep[2025], 4_799_066, source="cow-tools examples/wp0_oracle.rs (f)") ``` ```text PASS 2024 bovinos: cube = CSV: 11,449,817 vs 11,449,817 (exactly) — datosanimales.csv 2024, column AnimalesPorEspeciePD_AD PASS 2024 bovinos de leche: cube = CSV: 688,331 vs 688,331 (exactly) — datosanimales.csv 2024, column AnimalesPorEspeciePD_AD PASS 2024 ovinos: cube = CSV: 5,420,661 vs 5,420,661 (exactly) — datosanimales.csv 2024, column AnimalesPorEspeciePD_AD PASS 2024 yeguarizos: cube = CSV: 398,724 vs 398,724 (exactly) — datosanimales.csv 2024, column AnimalesPorEspeciePD_AD PASS 2024 caprinos: cube = CSV: 9,772 vs 9,772 (exactly) — datosanimales.csv 2024, column AnimalesPorEspeciePD_AD PASS 2024 suinos: cube = CSV: 110,583 vs 110,583 (exactly) — datosanimales.csv 2024, column AnimalesPorEspeciePD_AD PASS 2024: one observation per CSV row: 80,480 vs 80,480 (exactly) — datosanimales.csv 2024 has 80,480 data rows ``` ```text PASS 2025 bovinos: cube = CSV: 11,583,321 vs 11,583,321 (exactly) — datosanimales.csv 2025, column AnimalesPorEspeciePD_AD PASS 2025 bovinos de leche: cube = CSV: 681,948 vs 681,948 (exactly) — datosanimales.csv 2025, column AnimalesPorEspeciePD_AD PASS 2025 ovinos: cube = CSV: 4,799,066 vs 4,799,066 (exactly) — datosanimales.csv 2025, column AnimalesPorEspeciePD_AD PASS 2025 yeguarizos: cube = CSV: 405,813 vs 405,813 (exactly) — datosanimales.csv 2025, column AnimalesPorEspeciePD_AD PASS 2025 caprinos: cube = CSV: 10,415 vs 10,415 (exactly) — datosanimales.csv 2025, column AnimalesPorEspeciePD_AD PASS 2025 suinos: cube = CSV: 117,040 vs 117,040 (exactly) — datosanimales.csv 2025, column AnimalesPorEspeciePD_AD PASS 2025: one observation per CSV row: 79,096 vs 79,096 (exactly) — datosanimales.csv 2025 has 79,096 data rows PASS 2024 cattle (WP-0 oracle): 12,138,148 vs 12,138,148 (exactly) — cow-tools examples/wp0_oracle.rs (b) PASS 2025 cattle (WP-0 oracle): 12,265,269 vs 12,265,269 (exactly) — cow-tools examples/wp0_oracle.rs (b) PASS 2025 sheep (WP-0 oracle): 4,799,066 vs 4,799,066 (exactly) — cow-tools examples/wp0_oracle.rs (f) ``` ### The chart Horses, pigs and goats are in the declaration too, but DICOSE says plainly in its data dictionary that their numbers are "included for reference, without quality control". They are shown, greyed, for completeness. ```python labels = {"1": "Cattle (beef)", "11": "Cattle (dairy)", "2": "Sheep", "3": "Horses", "5": "Pigs", "4": "Goats"} bars = species.query("year == 2025").assign( name=lambda d: d["code"].map(labels), checked=lambda d: d["code"].isin(["1", "11", "2"]).map({True: "quality-controlled", False: "reference only"}), ) base = alt.Chart(bars, title=alt.Title("Animals declared on 30 June 2025", subtitle="DICOSE sworn declarations, stock on the holding (PD_AD)")).encode( y=alt.Y("name:N", sort="-x", title=None), x=alt.X("animals:Q", title="animals", axis=alt.Axis(format="~s")), tooltip=[alt.Tooltip("name:N", title="species"), alt.Tooltip("animals:Q", format=",")], ) chart = base.mark_bar(height=18).encode( color=alt.Color("checked:N", scale=alt.Scale(domain=["quality-controlled", "reference only"], range=[cc.CATTLE, cc.MUTED]), title=None)) text = base.mark_text(align="left", dx=4).encode(text=alt.Text("animals:Q", format=",")) cc.show((chart + text).properties(width=520, height=200), "species-2025", alt_text="Horizontal bars: beef cattle 11.6 million, sheep 4.8 million, dairy cattle 0.68 million, horses, pigs and goats far smaller.") ``` ![Horizontal bars: beef cattle 11.6 million, sheep 4.8 million, dairy cattle 0.68 million, horses, pigs and goats far smaller.](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/species-2025.svg) Chart data and encoding: [charts/species-2025.vl.json](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/species-2025.vl.json) (Vega-Lite). ## Where the cattle are The same observations grouped by department. Every observation carries its department as an IRI from the DICOSE department codelist (`urn:sophia:cow:department/`); the map joins that code to Natural Earth's outlines of the 19 departments. ```python by_dept = cw.sparql(""" SELECT ?department ?year (SUM(?n) AS ?cattle) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year ?year ; cow:department ?department ; cow:species ?species ; cow:animalsCount ?n . VALUES ?species { } } } GROUP BY ?department ?year """) by_dept["code"] = by_dept["department"].map(cw.dept_code) depts = cw.departments() cattle_dept = (by_dept.pivot(index="code", columns="year", values="cattle").reset_index() .merge(depts[["code", "name"]], on="code")) cattle_dept.columns = ["code", "cattle_2024", "cattle_2025", "name"] cattle_dept = cattle_dept.sort_values("cattle_2025", ascending=False) cw.check("19 departments", len(cattle_dept), 19, source="DICOSE codigosdepartamentos.csv") cw.check("2025 departments sum to the national total", int(cattle_dept["cattle_2025"].sum()), cattle[2025], source="same cube, two groupings") cc.show_table(cattle_dept[["name", "cattle_2025", "cattle_2024"]], name="cattle-by-department") ``` ```text PASS 19 departments: 19 vs 19 (exactly) — DICOSE codigosdepartamentos.csv PASS 2025 departments sum to the national total: 12,265,269 vs 12,265,269 (exactly) — same cube, two groupings ``` | name | cattle_2025 | cattle_2024 | |:---------------|:--------------|:--------------| | Florida | 1,117,097 | 1,095,226 | | Tacuarembó | 1,061,136 | 1,034,575 | | Durazno | 952,171 | 900,286 | | Cerro Largo | 950,412 | 957,379 | | Salto | 898,899 | 849,010 | | Paysandú | 801,512 | 809,798 | | Artigas | 742,198 | 730,165 | | Rocha | 682,644 | 688,313 | | Lavalleja | 654,451 | 644,438 | | Rivera | 639,917 | 608,407 | | Treinta y Tres | 584,734 | 613,051 | | Soriano | 567,452 | 570,050 | | Río Negro | 549,369 | 555,782 | | San José | 541,254 | 548,346 | | Colonia | 537,066 | 551,213 | | Flores | 409,429 | 393,191 | | Canelones | 338,601 | 355,686 | | Maldonado | 234,191 | 230,533 | | Montevideo | 2,736 | 2,699 | ```python top = cattle_dept.iloc[0] small = cattle_dept.iloc[-1] cw.finding("where", f"**{top['name']}** has the most cattle ({int(top['cattle_2025']):,}); " f"{small['name']} the fewest ({int(small['cattle_2025']):,}). " f"The five largest departments hold {cattle_dept['cattle_2025'].head(5).sum()/cattle[2025]:.1%} of the national herd.") ``` > **Finding.** **Florida** has the most cattle (1,117,097); Montevideo the fewest (2,736). The five largest departments hold 40.6% of the national herd. ```python cc.show( cc.choropleth(cattle_dept, "cattle_2025", title="Cattle by department, 2025", subtitle="beef + dairy, animals on the holding (PD_AD)", legend="cattle", fmt=",.0f"), "cattle-map-2025", thumbnail=True, alt_text="Map of Uruguay's 19 departments shaded by cattle; the darkest are in the centre and north (Florida, Tacuarembó, Durazno, Cerro Largo), the lightest is Montevideo.") print(cc.map_credit()) ``` ![Map of Uruguay's 19 departments shaded by cattle; the darkest are in the centre and north (Florida, Tacuarembó, Durazno, Cerro Largo), the lightest is Montevideo.](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/cattle-map-2025.svg) Chart data and encoding: [charts/cattle-map-2025.vl.json](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/cattle-map-2025.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ## The cross-check, against the curated tools The demo also answers through its curated `cow_*` MCP tools, which run their own SPARQL over the same cube. `cow_rank` ranks departments by a metric; the sum of its rows must be the same national total. ```python tools = cw.list_tools() if "cow_rank" in tools: ranked = cw.tool("cow_rank", metric="bovine_count", entity="department", year=2025, direction="top", limit=20) rows = ranked.get("results", ranked) if isinstance(ranked, dict) else ranked rows = rows.get("rows", rows) if isinstance(rows, dict) else rows cw.check("cow_rank bovine_count 2025 sums to the national total", int(round(sum(float(r["value"]) for r in rows))), cattle[2025], source="cow_rank via /mcp") else: print(f"NOT RUN: this endpoint has no cow_rank tool yet ({len(tools)} tools listed). " "The SPARQL and CSV checks above still hold.") ``` ```text PASS cow_rank bovine_count 2025 sums to the national total: 12,265,269 vs 12,265,269 (exactly) — cow_rank via /mcp ``` ## Where every number came from The queries this notebook ran, and every cross-check, with its source. ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:------------------------------------------------------|:-----------|:-----------|:--------|:-------------------------------------------------------| | 2024 bovinos: cube = CSV | 11,449,817 | 11,449,817 | exactly | datosanimales.csv 2024, column AnimalesPorEspeciePD_AD | | 2024 bovinos de leche: cube = CSV | 688,331 | 688,331 | exactly | datosanimales.csv 2024, column AnimalesPorEspeciePD_AD | | 2024 ovinos: cube = CSV | 5,420,661 | 5,420,661 | exactly | datosanimales.csv 2024, column AnimalesPorEspeciePD_AD | | 2024 yeguarizos: cube = CSV | 398,724 | 398,724 | exactly | datosanimales.csv 2024, column AnimalesPorEspeciePD_AD | | 2024 caprinos: cube = CSV | 9,772 | 9,772 | exactly | datosanimales.csv 2024, column AnimalesPorEspeciePD_AD | | 2024 suinos: cube = CSV | 110,583 | 110,583 | exactly | datosanimales.csv 2024, column AnimalesPorEspeciePD_AD | | 2024: one observation per CSV row | 80,480 | 80,480 | exactly | datosanimales.csv 2024 has 80,480 data rows | | 2025 bovinos: cube = CSV | 11,583,321 | 11,583,321 | exactly | datosanimales.csv 2025, column AnimalesPorEspeciePD_AD | | 2025 bovinos de leche: cube = CSV | 681,948 | 681,948 | exactly | datosanimales.csv 2025, column AnimalesPorEspeciePD_AD | | 2025 ovinos: cube = CSV | 4,799,066 | 4,799,066 | exactly | datosanimales.csv 2025, column AnimalesPorEspeciePD_AD | | 2025 yeguarizos: cube = CSV | 405,813 | 405,813 | exactly | datosanimales.csv 2025, column AnimalesPorEspeciePD_AD | | 2025 caprinos: cube = CSV | 10,415 | 10,415 | exactly | datosanimales.csv 2025, column AnimalesPorEspeciePD_AD | | 2025 suinos: cube = CSV | 117,040 | 117,040 | exactly | datosanimales.csv 2025, column AnimalesPorEspeciePD_AD | | 2025: one observation per CSV row | 79,096 | 79,096 | exactly | datosanimales.csv 2025 has 79,096 data rows | | 2024 cattle (WP-0 oracle) | 12,138,148 | 12,138,148 | exactly | cow-tools examples/wp0_oracle.rs (b) | | 2025 cattle (WP-0 oracle) | 12,265,269 | 12,265,269 | exactly | cow-tools examples/wp0_oracle.rs (b) | | 2025 sheep (WP-0 oracle) | 4,799,066 | 4,799,066 | exactly | cow-tools examples/wp0_oracle.rs (f) | | 19 departments | 19 | 19 | exactly | DICOSE codigosdepartamentos.csv | | 2025 departments sum to the national total | 12,265,269 | 12,265,269 | exactly | same cube, two groupings | | cow_rank bovine_count 2025 sums to the national total | 12,265,269 | 12,265,269 | exactly | cow_rank via /mcp | ```text kind target rows \ 0 sparql uruguay-cows 12.0 1 sparql uruguay-cows 38.0 2 tool cow_rank NaN first line 0 SELECT ?year ?species (SUM(?n) AS ?animals) (S... 1 SELECT ?department ?year (SUM(?n) AS ?cattle) 2 {"metric": "bovine_count", "entity": "departme... ``` ```python cw.save() ``` --- ### Cattle and sheep, department by department Finding: Only Salto and Artigas still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell 11.5% in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep. Page: https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/cattle-and-sheep.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.md # Cattle and sheep, department by department **Answer.** Only **Salto and Artigas** still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell **11.5%** in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep. Notebook: https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/cattle-and-sheep.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## Findings - Only **Salto and Artigas** still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell **11.5%** in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep. - Every one of the 19 departments declared fewer sheep in 2025. The steepest fall was in **Río Negro** (-18.3%); in absolute heads, Salto lost the most (118,943). ## The notebook Uruguay is a cattle country, but the north is still sheep country: on the basalt of Salto and Artigas there are more sheep than cattle. Wool built the old estancias; the national flock has been shrinking for decades. This notebook asks how the two herds split across the 19 departments, and what one year (2024 → 2025) did to the sheep. A note on comparing a sheep with a cow: we compare **heads**, the unit DICOSE counts. In livestock units a sheep weighs far less (DICOSE's own codelist weights a breeding ewe at 0.17 of a unit, a breeding cow at 1.03), so a department that is "half sheep" by heads is still mostly cattle by grass eaten. ```python # Setup. import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc ``` ```python # The query: cattle (beef + dairy) and sheep per department, both years. q = cw.sparql(""" SELECT ?department ?year ?kind (SUM(?n) AS ?animals) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year ?year ; cow:department ?department ; cow:species ?species ; cow:animalsCount ?n . VALUES (?species ?kind) { ( "cattle") ( "cattle") ( "sheep") } } } GROUP BY ?department ?year ?kind """) q["code"] = q["department"].map(cw.dept_code) t = q.pivot_table(index="code", columns=["kind", "year"], values="animals", aggfunc="sum") t.columns = [f"{k}_{y}" for k, y in t.columns] t = t.reset_index().merge(cw.departments()[["code", "name"]], on="code") for y in (2024, 2025): t[f"sheep_share_{y}"] = t[f"sheep_{y}"] / (t[f"sheep_{y}"] + t[f"cattle_{y}"]) t["sheep_change"] = t["sheep_2025"] / t["sheep_2024"] - 1 t["cattle_change"] = t["cattle_2025"] / t["cattle_2024"] - 1 t = t.sort_values("sheep_share_2025", ascending=False) cc.show_table(t[["name", "cattle_2025", "sheep_2025", "sheep_share_2025", "sheep_change"]] .rename(columns={"sheep_share_2025": "sheep share of heads", "sheep_change": "sheep 2024→25"}), floatfmt=".3f", name="by-department") ``` | name | cattle_2025 | sheep_2025 | sheep share of heads | sheep 2024→25 | |:---------------|:--------------|:-------------|-----------------------:|----------------:| | Salto | 898,899 | 1,032,181 | 0.535 | -0.103 | | Artigas | 742,198 | 801,403 | 0.519 | -0.098 | | Montevideo | 2,736 | 2,369 | 0.464 | -0.004 | | Paysandú | 801,512 | 555,079 | 0.409 | -0.149 | | Maldonado | 234,191 | 101,340 | 0.302 | -0.061 | | Lavalleja | 654,451 | 261,086 | 0.285 | -0.099 | | Tacuarembó | 1,061,136 | 398,742 | 0.273 | -0.122 | | Cerro Largo | 950,412 | 303,495 | 0.242 | -0.129 | | Durazno | 952,171 | 290,920 | 0.234 | -0.131 | | Treinta y Tres | 584,734 | 178,572 | 0.234 | -0.142 | | Rivera | 639,917 | 182,585 | 0.222 | -0.094 | | Rocha | 682,644 | 154,813 | 0.185 | -0.088 | | Flores | 409,429 | 83,001 | 0.169 | -0.13 | | Florida | 1,117,097 | 202,434 | 0.153 | -0.114 | | Canelones | 338,601 | 50,487 | 0.13 | -0.041 | | Río Negro | 549,369 | 69,144 | 0.112 | -0.183 | | Soriano | 567,452 | 55,293 | 0.089 | -0.097 | | Colonia | 537,066 | 38,341 | 0.067 | -0.158 | | San José | 541,254 | 37,781 | 0.065 | -0.152 | ### Cross-check against the source Re-derive the 2025 department totals from `datosanimales.csv` and compare every department, both species, to the head. Then compare three shares with the figures the July 2026 expedition published (Salto 53.5% sheep, Artigas 51.9%, San José 6.5%). ```python csv = cw.source_csv(2025, "datosanimales.csv") csv["n"] = cw.num(csv["AnimalesPorEspeciePD_AD"]) csv["kind"] = csv["EspecieCodigo"].map({"1": "cattle", "11": "cattle", "2": "sheep"}) src = csv.dropna(subset=["kind"]).groupby(["DepartamentoCodigo", "kind"])["n"].sum().unstack() mismatches = 0 for _, row in t.iterrows(): for kind in ("cattle", "sheep"): if int(row[f"{kind}_2025"]) != int(src.loc[row["code"], kind]): mismatches += 1 cw.check("2025 cattle and sheep, all 19 departments: cube = CSV (mismatching cells)", mismatches, 0, source="datosanimales.csv 2025, AnimalesPorEspeciePD_AD") share = t.set_index("name")["sheep_share_2025"] cw.check("Salto sheep share of heads", round(share["Salto"], 3), 0.535, tol=0.0005, source="expedition 2026-07-05") cw.check("Artigas sheep share of heads", round(share["Artigas"], 3), 0.519, tol=0.0005, source="expedition 2026-07-05") cw.check("San José sheep share of heads", round(share["San José"], 3), 0.065, tol=0.0005, source="expedition 2026-07-05") ``` ```text PASS 2025 cattle and sheep, all 19 departments: cube = CSV (mismatching cells): 0 vs 0 (exactly) — datosanimales.csv 2025, AnimalesPorEspeciePD_AD PASS Salto sheep share of heads: 0.535 vs 0.535 (within ±0.0005) — expedition 2026-07-05 PASS Artigas sheep share of heads: 0.519 vs 0.519 (within ±0.0005) — expedition 2026-07-05 PASS San José sheep share of heads: 0.065 vs 0.065 (within ±0.0005) — expedition 2026-07-05 ``` ```python sheep_n = {y: int(t[f"sheep_{y}"].sum()) for y in (2024, 2025)} fall = sheep_n[2025] / sheep_n[2024] - 1 cw.check("national sheep 2024 → 2025", round(fall, 4), -0.1147, tol=0.00005, source="expedition 2026-07-05: −11.47%") majority = t.query("sheep_share_2025 > 0.5")["name"].tolist() cw.finding("headline", f"Only **{' and '.join(majority)}** still have more sheep than cattle by heads " f"({share['Salto']:.1%} and {share['Artigas']:.1%} sheep). The national flock fell " f"**{-fall:.1%}** in one year, from {sheep_n[2024]:,} to {sheep_n[2025]:,}: " f"{sheep_n[2024]-sheep_n[2025]:,} fewer sheep.") ``` ```text PASS national sheep 2024 → 2025: -0.1147 vs -0.1147 (within ±5e-05) — expedition 2026-07-05: −11.47% ``` > **Finding.** Only **Salto and Artigas** still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell **11.5%** in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep. ## The map: where the sheep are Share of heads that are sheep, 2025. The north-west basalt (Artigas, Salto, Paysandú) is the old sheep country; the dairy south-west is nearly free of them. ```python cc.show(cc.choropleth(t, "sheep_share_2025", title="Sheep as a share of cattle + sheep, 2025", subtitle="heads on the holding (PD_AD)", legend="sheep share", fmt=".0%", domain=[0, 0.6]), "sheep-share-map-2025", thumbnail=True, alt_text="Map: sheep are over half the heads in Salto and Artigas; Montevideo (46%, a few thousand animals) and Paysandú (41%) follow; lowest in San José and Colonia.") print(cc.map_credit()) ``` ![Map: sheep are over half the heads in Salto and Artigas; Montevideo (46%, a few thousand animals) and Paysandú (41%) follow; lowest in San José and Colonia.](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-share-map-2025.svg) Chart data and encoding: [charts/sheep-share-map-2025.vl.json](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-share-map-2025.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ## The decline, department by department Every department lost sheep between the two declarations. The map is coloured on a diverging scale centred on zero, so a department that had gained would show blue; none did. ```python lost_all = bool((t["sheep_change"] < 0).all()) worst = t.sort_values("sheep_change").iloc[0] cw.check("every department lost sheep", lost_all, True, source="the table above") cc.show(cc.choropleth(t, "sheep_change", title="Change in sheep, 2024 → 2025", subtitle="per department; brown is a fall, blue a rise", legend="change", fmt="+.0%", diverging=True), "sheep-change-map", alt_text="Diverging map: every department is brown, a fall in sheep everywhere; the steepest is Río Negro.") ``` ```text PASS every department lost sheep: True vs True (exactly) — the table above ``` ![Diverging map: every department is brown, a fall in sheep everywhere; the steepest is Río Negro.](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-change-map.svg) Chart data and encoding: [charts/sheep-change-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-change-map.vl.json) (Vega-Lite). ```python cw.finding("decline", f"Every one of the 19 departments declared fewer sheep in 2025. The steepest fall was in " f"**{worst['name']}** ({worst['sheep_change']:+.1%}); in absolute heads, " f"{t.assign(d=t.sheep_2024 - t.sheep_2025).sort_values('d').iloc[-1]['name']} lost the most " f"({int(t.assign(d=t.sheep_2024 - t.sheep_2025)['d'].max()):,}).") ``` > **Finding.** Every one of the 19 departments declared fewer sheep in 2025. The steepest fall was in **Río Negro** (-18.3%); in absolute heads, Salto lost the most (118,943). ## Small multiples: both herds, both years One panel per department, cattle and sheep side by side, 2024 and 2025. The panels share a scale, so the size of each department's herd is comparable. ```python long = pd.concat([ t[["name", f"{k}_{y}"]].rename(columns={f"{k}_{y}": "animals"}).assign(kind=k, year=str(y)) for k in ("cattle", "sheep") for y in (2024, 2025) ]) order = t.sort_values("cattle_2025", ascending=False)["name"].tolist() sm = ( alt.Chart(long) .mark_bar() .encode( x=alt.X("year:N", title=None, axis=alt.Axis(labelAngle=0)), xOffset="kind:N", y=alt.Y("animals:Q", title=None, axis=alt.Axis(format="~s", tickCount=3)), color=alt.Color("kind:N", scale=alt.Scale(domain=["cattle", "sheep"], range=[cc.CATTLE, cc.SHEEP]), title=None), tooltip=["name:N", "kind:N", "year:N", alt.Tooltip("animals:Q", format=",")], ) .properties(width=95, height=80) .facet(facet=alt.Facet("name:N", sort=order, title=None), columns=5) .properties(title=alt.Title("Cattle and sheep by department, 2024 and 2025", subtitle="heads on the holding; panels ordered by cattle, largest first")) ) cc.show(sm, "small-multiples", alt_text="Nineteen small panels, one per department, each with cattle and sheep bars for 2024 and 2025; sheep bars shrink everywhere.") ``` ![Nineteen small panels, one per department, each with cattle and sheep bars for 2024 and 2025; sheep bars shrink everywhere.](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/small-multiples.svg) Chart data and encoding: [charts/small-multiples.vl.json](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/small-multiples.vl.json) (Vega-Lite). ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:--------------------------------------------------------------------------|--------:|-----------:|:---------------|:------------------------------------------------| | 2025 cattle and sheep, all 19 departments: cube = CSV (mismatching cells) | 0 | 0 | exactly | datosanimales.csv 2025, AnimalesPorEspeciePD_AD | | Salto sheep share of heads | 0.535 | 0.535 | within ±0.0005 | expedition 2026-07-05 | | Artigas sheep share of heads | 0.519 | 0.519 | within ±0.0005 | expedition 2026-07-05 | | San José sheep share of heads | 0.065 | 0.065 | within ±0.0005 | expedition 2026-07-05 | | national sheep 2024 → 2025 | -0.1147 | -0.1147 | within ±5e-05 | expedition 2026-07-05: −11.47% | | every department lost sheep | 1 | 1 | exactly | the table above | ```text kind target rows \ 0 sparql uruguay-cows 76 first line 0 SELECT ?department ?year ?kind (SUM(?n) AS ?an... ``` ```python cw.save() ``` --- ### Dairy country Finding: Florida, San José, Colonia produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%. Page: https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/dairy-country/dairy-country.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.md # Dairy country **Answer.** **Florida, San José, Colonia** produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%. Notebook: https://cow-tools.sophia-labs.com/notebooks/dairy-country/dairy-country.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## Findings - Of the 2,298,402,318 litres declared in 2025, **318,070 were goat's milk**, 60% of it from San José. - **Florida, San José, Colonia** produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%. - Florida had **100,116 dairy cows** on 30 June 2025 by DICOSE's dairy convention (own animals, PD_PF), or 103,472 counting the animals on its holdings (PD_AD); 182,610 dairy cattle of all ages. - **San José** produces 1,605 litres per hectare of livestock land, 2.5× Florida's 645: Florida has the volume, San José the intensity. ## The notebook Uruguay's milk comes from a compact basin in the south-west, the *cuenca lechera*: Florida, San José and Colonia, with Canelones, Soriano and Durazno at its edges. DICOSE asks every dairy holder how many litres they produced in the year and where the milk went (sold to industry, made into cheese on the farm, drunk at home, fed to calves). Three questions: how much milk, where, and how many dairy cows make it. The third has a trap in it, and we fall into it on purpose. ```python # Setup. import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc names = cc.department_names() ``` ## How much milk, and where `produccionleche.csv` becomes `cow:MilkProductionObservation`s carrying `cow:milkLiters` (an exact decimal), the species, and a production type (the destination of the milk). ```python # The query: litres per department and species, both years. milk = cw.sparql(""" SELECT ?year ?department ?species (SUM(?l) AS ?litres) (COUNT(?obs) AS ?observations) WHERE { GRAPH ?g { ?obs a cow:MilkProductionObservation ; cow:year ?year ; cow:department ?department ; cow:species ?species ; cow:milkLiters ?l . } } GROUP BY ?year ?department ?species """) milk["code"] = milk["department"].map(cw.dept_code) milk["name"] = milk["code"].map(names) milk["species_code"] = milk["species"].map(cw.dept_code) milk["litres"] = milk["litres"].astype(float) by_species = milk.groupby(["year", "species_code"])["litres"].sum().unstack() by_species ``` ```text species_code 11 4 year 2024 2.259792e+09 775272.0 2025 2.298084e+09 318070.0 ``` Two species give milk in the declaration: dairy cattle (`11`) and, in a handful of rows, **goats** (`4`). Uruguay's national milk total, as published, includes a few hundred thousand litres of goat's milk. For the dairy-basin shares below we keep both, as the published total does, and say so. ```python total = milk.groupby("year")["litres"].sum() goat = by_species.get("4", pd.Series(0, index=by_species.index)).fillna(0) goat_dept = milk.query("year == 2025 and species_code == '4'").sort_values("litres", ascending=False) cw.finding("goats", f"Of the {total[2025]:,.0f} litres declared in 2025, **{goat[2025]:,.0f} were goat's milk**, " f"{goat_dept.iloc[0]['litres'] / goat[2025]:.0%} of it from {goat_dept.iloc[0]['name']}.") ``` > **Finding.** Of the 2,298,402,318 litres declared in 2025, **318,070 were goat's milk**, 60% of it from San José. ```python dept = (milk.groupby(["year", "code", "name"])["litres"].sum().reset_index() .pivot_table(index=["code", "name"], columns="year", values="litres").reset_index()) dept.columns = ["code", "name", "litres_2024", "litres_2025"] dept["share_2025"] = dept["litres_2025"] / total[2025] dept = dept.sort_values("litres_2025", ascending=False) basin = dept.head(3) cc.show_table(dept[["name", "litres_2025", "share_2025", "litres_2024"]].head(8), floatfmt=",.3f", name="milk-by-department") ``` | name | litres_2025 | share_2025 | litres_2024 | |:----------|:----------------|-------------:|:----------------| | Florida | 608,116,907.000 | 0.265 | 589,491,996.000 | | San José | 520,036,099.000 | 0.226 | 506,304,257.000 | | Colonia | 441,387,725.000 | 0.192 | 437,896,008.000 | | Durazno | 212,599,351.000 | 0.092 | 205,096,846.000 | | Soriano | 132,200,132.000 | 0.058 | 131,464,129.000 | | Canelones | 112,534,896.000 | 0.049 | 110,567,310.000 | | Río Negro | 82,430,061.000 | 0.036 | 84,098,833.000 | | Flores | 56,347,358.000 | 0.025 | 60,006,073.000 | ### Cross-check against the source The litres per department, re-summed from `produccionleche.csv` (both years, every department, every species), must match the cube to the litre. Then the shares the July 2026 expedition published: Florida 26.5%, San José 22.6%, Colonia 19.2%, together 68.3% of 2,298.4 million litres; national milk +1.67% on 2024. ```python for year in (2024, 2025): csv = cw.source_csv(year, "produccionleche.csv") s = cw.num(csv["Litros"]).groupby(csv["DepartamentoCodigo"]).sum() cube = milk.query("year == @year").groupby("code")["litres"].sum() diff = (cube - s.reindex(cube.index)).abs().max() cw.check(f"{year} litres per department: cube = CSV (largest difference, litres)", float(diff), 0.0, source=f"produccionleche.csv {year}, column Litros") cw.check(f"{year} national litres: cube = CSV", float(total[year]), float(s.sum()), source="produccionleche.csv") share = dept.set_index("name")["share_2025"] cw.check("Florida share of milk", round(share["Florida"], 3), 0.265, tol=0.0005, source="expedition 2026-07-05") cw.check("San José share of milk", round(share["San José"], 3), 0.226, tol=0.0005, source="expedition 2026-07-05") cw.check("Colonia share of milk", round(share["Colonia"], 3), 0.192, tol=0.0005, source="expedition 2026-07-05") cw.check("2025 national milk, millions of litres", round(total[2025] / 1e6, 1), 2298.4, tol=0.05, source="expedition 2026-07-05") cw.check("milk 2024 → 2025", round(total[2025] / total[2024] - 1, 4), 0.0167, tol=0.00005, source="expedition 2026-07-05: +1.67%") cw.finding("headline", f"**{', '.join(basin['name'])}** produce {basin['share_2025'].sum():.1%} of Uruguay's milk " f"({total[2025]/1e6:,.1f} million litres in 2025, {total[2025]/total[2024]-1:+.2%} on 2024). " f"{basin.iloc[0]['name']} makes the most: {basin.iloc[0]['share_2025']:.1%}.") ``` ```text PASS 2024 litres per department: cube = CSV (largest difference, litres): 0 vs 0 (exactly) — produccionleche.csv 2024, column Litros PASS 2024 national litres: cube = CSV: 2,260,567,177 vs 2,260,567,177 (exactly) — produccionleche.csv PASS 2025 litres per department: cube = CSV (largest difference, litres): 0 vs 0 (exactly) — produccionleche.csv 2025, column Litros PASS 2025 national litres: cube = CSV: 2,298,402,318 vs 2,298,402,318 (exactly) — produccionleche.csv PASS Florida share of milk: 0.265 vs 0.265 (within ±0.0005) — expedition 2026-07-05 PASS San José share of milk: 0.226 vs 0.226 (within ±0.0005) — expedition 2026-07-05 PASS Colonia share of milk: 0.192 vs 0.192 (within ±0.0005) — expedition 2026-07-05 PASS 2025 national milk, millions of litres: 2,298 vs 2,298 (within ±0.05) — expedition 2026-07-05 PASS milk 2024 → 2025: 0.0167 vs 0.0167 (within ±5e-05) — expedition 2026-07-05: +1.67% ``` > **Finding.** **Florida, San José, Colonia** produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%. ```python cc.show(cc.choropleth(dept, "share_2025", title="Share of Uruguay's milk, 2025", subtitle="litres declared to DICOSE, all destinations", legend="share of national milk", fmt=".1%"), "milk-share-map", thumbnail=True, alt_text="Map: milk is concentrated in Florida, San José and Colonia in the south-west; the north and east produce almost none.") print(cc.map_credit()) ``` ![Map: milk is concentrated in Florida, San José and Colonia in the south-west; the north and east produce almost none.](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/milk-share-map.svg) Chart data and encoding: [charts/milk-share-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/milk-share-map.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ## How many dairy cows? (the trap) Ask "how many dairy cows are in Florida?" and the cube can give you three honest answers, because the question is ambiguous twice over: 1. **dairy cattle or dairy cows?** Species `11` counts bulls, heifers and calves too. The cows are two categories: *vacas en ordeñe* (milking) and *vacas secas* (dry). 2. **which stock?** DICOSE publishes two stock columns. `PD_AD` (own and others' animals *on* the holding) is the traditional stock. `PD_PF` (the holder's *own* animals, here or elsewhere) is, in DICOSE's own data dictionary, the one "used to measure livestock associated with dairy production". The cube carries both (`cow:animalsCount` and `cow:animalsCountPf`) on every category observation. Here they are side by side. ```python # The query: Florida's dairy cattle by category, both stock columns, 2025. cats = cw.sparql(""" SELECT ?category (SUM(?n) AS ?pd_ad) (SUM(?pf) AS ?pd_pf) WHERE { GRAPH ?g { ?obs a cow:AnimalCategoryStockObservation ; cow:year "2025"^^xsd:gYear ; cow:department ; cow:species ; cow:animalCategory ?category ; cow:animalsCount ?n . OPTIONAL { ?obs cow:animalsCountPf ?pf } } } GROUP BY ?category """) # Labels in their own query: the codelists live in one named graph per year, so joining them into the # sum above would count every animal twice (once per year's codelist). labels = cw.sparql(""" SELECT DISTINCT ?category ?label WHERE { GRAPH ?c { ?category skos:prefLabel ?label } FILTER(STRSTARTS(STR(?category), "urn:sophia:cow:animal-category/11/")) } """).drop_duplicates("category") cats = cats.merge(labels, on="category", how="left") cats["code"] = cats["category"].map(cw.dept_code) cats = cats.sort_values("code", key=lambda s: s.astype(int)) cows = cats[cats["code"].isin(["2", "3"])] answer = { "dairy cattle, PD_AD": int(cats["pd_ad"].sum()), "dairy cows (milking + dry), PD_AD": int(cows["pd_ad"].sum()), "dairy cows (milking + dry), PD_PF": int(cows["pd_pf"].sum()), } cc.show_table(cats[["code", "label", "pd_ad", "pd_pf"]], name="florida-dairy-categories") pd.Series(answer, name="Florida, 2025") ``` | code | label | pd_ad | pd_pf | |-------:|:--------------------------------------------|:--------|:--------| | 1 | 1) TOROS | 1,026 | 1,080 | | 2 | 2) VACAS EN ORDEÑE | 81,547 | 79,048 | | 3 | 3) VACAS SECAS | 21,925 | 21,068 | | 4 | 4) VAQUILLONAS DE MÁS DE 2 AÑOS SIN ENTORAR | 7,132 | 7,841 | | 5 | 5) VAQUILLONAS DE 1 Ó 2 AÑOS | 25,899 | 27,478 | | 6 | 6) TERNEROS DE MENOS DE 1 AÑO | 11,059 | 11,079 | | 7 | 7) TERNERAS DE MENOS DE 1 AÑO | 34,022 | 34,282 | ```text dairy cattle, PD_AD 182610 dairy cows (milking + dry), PD_AD 103472 dairy cows (milking + dry), PD_PF 100116 Name: Florida, 2025, dtype: int64 ``` ```python csv = cw.source_csv(2025, "datosanimalesdetallados.csv") fl = csv[(csv["DepartamentoCodigo"] == "7") & (csv["EspecieCodigo"] == "11")] ad = cw.num(fl["AnimalesPorCategoriaPD_AD"]).groupby(fl["CategoriaCodigo"]).sum() pf = cw.num(fl["AnimalesPorCategoriaPD_PF"]).groupby(fl["CategoriaCodigo"]).sum() cw.check("Florida dairy cattle 2025 (PD_AD): cube = CSV", answer["dairy cattle, PD_AD"], int(ad.sum()), source="datosanimalesdetallados.csv 2025") cw.check("Florida dairy cows 2025 (PD_AD): cube = CSV", answer["dairy cows (milking + dry), PD_AD"], int(ad[["2", "3"]].sum()), source="datosanimalesdetallados.csv 2025, categories 2 and 3") cw.check("Florida dairy cows 2025 (PD_PF): cube = CSV", answer["dairy cows (milking + dry), PD_PF"], int(pf[["2", "3"]].sum()), source="datosanimalesdetallados.csv 2025, categories 2 and 3") cw.finding("florida-cows", f"Florida had **{answer['dairy cows (milking + dry), PD_PF']:,} dairy cows** on 30 June 2025 by DICOSE's " f"dairy convention (own animals, PD_PF), or {answer['dairy cows (milking + dry), PD_AD']:,} counting the " f"animals on its holdings (PD_AD); {answer['dairy cattle, PD_AD']:,} dairy cattle of all ages.") ``` ```text PASS Florida dairy cattle 2025 (PD_AD): cube = CSV: 182,610 vs 182,610 (exactly) — datosanimalesdetallados.csv 2025 PASS Florida dairy cows 2025 (PD_AD): cube = CSV: 103,472 vs 103,472 (exactly) — datosanimalesdetallados.csv 2025, categories 2 and 3 PASS Florida dairy cows 2025 (PD_PF): cube = CSV: 100,116 vs 100,116 (exactly) — datosanimalesdetallados.csv 2025, categories 2 and 3 ``` > **Finding.** Florida had **100,116 dairy cows** on 30 June 2025 by DICOSE's dairy convention (own animals, PD_PF), or 103,472 counting the animals on its holdings (PD_AD); 182,610 dairy cattle of all ages. ## Who is the most intensive? Florida milks the most; San José milks the hardest. Two derived ratios, computed here from measured observations: litres per holder of a dairy declaration, and litres per hectare of the department's livestock land (`cow:livestockHectares`, from `datosgenerales.csv`). The second is a department-wide yardstick, not a dairy-farm yield: it divides the milk by all the land grazed by anything. ```python # The query: holders declaring milk, and livestock hectares, per department, 2025. ratios = cw.sparql(""" SELECT ?department (SUM(?h) AS ?milk_holders) WHERE { GRAPH ?g { ?obs a cow:MilkProductionObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:holdersCount ?h . } } GROUP BY ?department """).merge(cw.sparql(""" SELECT ?department (SUM(?ha) AS ?livestock_ha) WHERE { GRAPH ?g { ?obs a cow:GeneralHoldingObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:livestockHectares ?ha . } } GROUP BY ?department """), on="department") ratios["code"] = ratios["department"].map(cw.dept_code) ratios = ratios.merge(dept[["code", "name", "litres_2025"]], on="code") ratios["livestock_ha"] = ratios["livestock_ha"].astype(float) ratios["litres_per_ha"] = ratios["litres_2025"] / ratios["livestock_ha"] ratios = ratios.sort_values("litres_per_ha", ascending=False) cc.show_table(ratios[["name", "litres_per_ha", "litres_2025", "livestock_ha"]].head(6), floatfmt=",.0f", name="intensity") ``` | name | litres_per_ha | litres_2025 | livestock_ha | |:----------|:----------------|:--------------|:---------------| | San José | 1,605 | 520,036,099 | 324,103 | | Colonia | 1,277 | 441,387,725 | 345,775 | | Florida | 645 | 608,116,907 | 942,195 | | Canelones | 462 | 112,534,896 | 243,465 | | Soriano | 268 | 132,200,132 | 493,507 | | Durazno | 217 | 212,599,351 | 981,607 | `milk_holders` sums a count that DICOSE repeats on every production-type row (a holder who sells milk and also makes cheese is counted on both rows), so it over-counts people; we do not divide by it. The hectare ratio has no such problem: `datosgenerales.csv` has one row per holding class. ```python r = ratios.set_index("name") cw.check("San José litres per livestock hectare", round(r.loc["San José", "litres_per_ha"]), 1604, tol=1, source="expedition 2026-07-05: 1,604 L/ha") csvg = cw.source_csv(2025, "datosgenerales.csv") ha = cw.num(csvg["SuperficieGanadera"]).groupby(csvg["DepartamentoCodigo"]).sum() cw.check("San José livestock hectares: cube = CSV", round(float(r.loc["San José", "livestock_ha"]), 2), round(float(ha["16"]), 2), source="datosgenerales.csv 2025, SuperficieGanadera") ratio = r.loc["San José", "litres_per_ha"] / r.loc["Florida", "litres_per_ha"] cw.finding("intensity", f"**San José** produces {r.loc['San José', 'litres_per_ha']:,.0f} litres per hectare of livestock land, " f"{ratio:.1f}× Florida's {r.loc['Florida', 'litres_per_ha']:,.0f}: Florida has the volume, San José the intensity.") ``` ```text PASS San José litres per livestock hectare: 1,605 vs 1,604 (within ±1) — expedition 2026-07-05: 1,604 L/ha PASS San José livestock hectares: cube = CSV: 324,103 vs 324,103 (exactly) — datosgenerales.csv 2025, SuperficieGanadera ``` > **Finding.** **San José** produces 1,605 litres per hectare of livestock land, 2.5× Florida's 645: Florida has the volume, San José the intensity. ```python base = alt.Chart(ratios.head(8), title=alt.Title("Litres of milk per hectare of livestock land, 2025", subtitle="department milk ÷ all livestock hectares (a yardstick, not a farm yield)")).encode( y=alt.Y("name:N", sort="-x", title=None), x=alt.X("litres_per_ha:Q", title="litres per hectare"), tooltip=["name:N", alt.Tooltip("litres_per_ha:Q", format=",.0f")], ) bar = base.mark_bar(height=16, color=cc.DAIRY) cc.show((bar + base.mark_text(align="left", dx=4).encode(text=alt.Text("litres_per_ha:Q", format=",.0f"))) .properties(width=480, height=190), "litres-per-ha", alt_text="Bars: San José leads at about 1,600 litres per livestock hectare, then Colonia (about 1,280) and Florida (about 650).") ``` ![Bars: San José leads at about 1,600 litres per livestock hectare, then Colonia (about 1,280) and Florida (about 650).](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/litres-per-ha.svg) Chart data and encoding: [charts/litres-per-ha.vl.json](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/litres-per-ha.vl.json) (Vega-Lite). ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:--------------------------------------------------------------------|:-----------------|:-----------------|:---------------|:-----------------------------------------------------| | 2024 litres per department: cube = CSV (largest difference, litres) | 0.00 | 0.00 | exactly | produccionleche.csv 2024, column Litros | | 2024 national litres: cube = CSV | 2,260,567,177.00 | 2,260,567,177.00 | exactly | produccionleche.csv | | 2025 litres per department: cube = CSV (largest difference, litres) | 0.00 | 0.00 | exactly | produccionleche.csv 2025, column Litros | | 2025 national litres: cube = CSV | 2,298,402,318.00 | 2,298,402,318.00 | exactly | produccionleche.csv | | Florida share of milk | 0.27 | 0.27 | within ±0.0005 | expedition 2026-07-05 | | San José share of milk | 0.23 | 0.23 | within ±0.0005 | expedition 2026-07-05 | | Colonia share of milk | 0.19 | 0.19 | within ±0.0005 | expedition 2026-07-05 | | 2025 national milk, millions of litres | 2,298.40 | 2,298.40 | within ±0.05 | expedition 2026-07-05 | | milk 2024 → 2025 | 0.02 | 0.02 | within ±5e-05 | expedition 2026-07-05: +1.67% | | Florida dairy cattle 2025 (PD_AD): cube = CSV | 182,610.00 | 182,610.00 | exactly | datosanimalesdetallados.csv 2025 | | Florida dairy cows 2025 (PD_AD): cube = CSV | 103,472.00 | 103,472.00 | exactly | datosanimalesdetallados.csv 2025, categories 2 and 3 | | Florida dairy cows 2025 (PD_PF): cube = CSV | 100,116.00 | 100,116.00 | exactly | datosanimalesdetallados.csv 2025, categories 2 and 3 | | San José litres per livestock hectare | 1,605.00 | 1,604.00 | within ±1 | expedition 2026-07-05: 1,604 L/ha | | San José livestock hectares: cube = CSV | 324,103.30 | 324,103.30 | exactly | datosgenerales.csv 2025, SuperficieGanadera | ```text kind target rows \ 0 sparql uruguay-cows 50 1 sparql uruguay-cows 7 2 sparql uruguay-cows 7 3 sparql uruguay-cows 19 4 sparql uruguay-cows 19 first line 0 SELECT ?year ?department ?species (SUM(?l) AS ... 1 SELECT ?category (SUM(?n) AS ?pd_ad) (SUM(?pf)... 2 SELECT DISTINCT ?category ?label 3 SELECT ?department (SUM(?h) AS ?milk_holders) 4 SELECT ?department (SUM(?ha) AS ?livestock_ha) ``` ```python cw.save() ``` --- ### Breeders in the east, finishers in the west Finding: Maldonado is the most breeding-heavy department: 71.7% of its beef herd is breeding cows and calves. Soriano leans hardest to finishing: 29.8% steers and fattening cows. The east breeds; the west finishes. Page: https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/herd-structure/herd-structure.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.md # Breeders in the east, finishers in the west **Answer.** **Maldonado** is the most breeding-heavy department: 71.7% of its beef herd is breeding cows and calves. **Soriano** leans hardest to finishing: 29.8% steers and fattening cows. The east breeds; the west finishes. Notebook: https://cow-tools.sophia-labs.com/notebooks/herd-structure/herd-structure.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## The notebook A beef herd is a pipeline: breeding cows have calves, calves become yearlings, steers are fattened and sold. Regions specialise. Where the land is poor, farmers keep cows and sell the calves (*cría*); where it is better, they buy those calves and finish them (*invernada*). The declaration's nine beef categories show which is which, department by department. The categories (`codigoscategoria.csv`, species 1): 1 bulls, 2 breeding cows (mated), 3 cows being fattened, 4–6 steers by age, 7–8 heifers, 9 calves. We fold them into four groups so the chart stays legible: **breeding** (2 breeding cows + 9 calves), **steers and fattening cows** (3, 4, 5, 6), **heifers** (7, 8) and **bulls** (1). ```python # Setup. import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc names = cc.department_names() GROUP = {"1": "bulls", "2": "breeding", "9": "breeding", "3": "steers & fattening cows", "4": "steers & fattening cows", "5": "steers & fattening cows", "6": "steers & fattening cows", "7": "heifers", "8": "heifers"} ``` ```python # The query: cattle (beef and dairy) by category and department, 2025, with the beef category labels. allcat = cw.sparql(""" SELECT ?department ?species ?category (SUM(?n) AS ?animals) WHERE { GRAPH ?g { ?obs a cow:AnimalCategoryStockObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:species ?species ; cow:animalCategory ?category ; cow:animalsCount ?n . VALUES ?species { } } } GROUP BY ?department ?species ?category """) cat = allcat[allcat["species"] == "urn:sophia:cow:species/1"].copy() labels = cw.sparql(""" SELECT DISTINCT ?category ?label WHERE { GRAPH ?g { ?category skos:prefLabel ?label } FILTER(STRSTARTS(STR(?category), "urn:sophia:cow:animal-category/1/")) } """) labels["code"] = labels["category"].map(cw.dept_code) labels = labels.drop_duplicates("code").sort_values("code", key=lambda s: s.astype(int)) cc.show_table(labels[["code", "label"]], name="beef-categories") ``` | code | label | |-------:|:-------------------------------------------| | 1 | 1) TOROS | | 2 | 2) VACAS DE CRIA (ENTORADAS) | | 3 | 3) VACAS DE INVERNADA | | 4 | 4) NOVILLOS DE MAS DE 3 AÑOS | | 5 | 5) NOVILLOS DE 2 A 3 AÑOS | | 6 | 6) NOVILLOS DE 1 A 2 AÑOS | | 7 | 7) VAQUILLONA DE MAS DE 2 AÑOS SIN ENTORAR | | 8 | 8) VAQUILLONAS DE 1 A 2 AÑOS | | 9 | 9) TERNEROS/TERNERAS | ```python cat["code"] = cat["department"].map(cw.dept_code) cat["cat_code"] = cat["category"].map(cw.dept_code) cat["group"] = cat["cat_code"].map(GROUP) cw.check("every beef category maps to a group", int(cat["group"].isna().sum()), 0, source="the 9 beef categories") wide = cat.pivot_table(index="code", columns="group", values="animals", aggfunc="sum").fillna(0) share = wide.div(wide.sum(axis=1), axis=0) share["name"] = share.index.map(names) share = share.sort_values("breeding", ascending=False) cc.show_table(share[["name", "breeding", "steers & fattening cows", "heifers", "bulls"]].reset_index(drop=True), floatfmt=".3f", name="group-shares") ``` ```text PASS every beef category maps to a group: 0 vs 0 (exactly) — the 9 beef categories ``` | name | breeding | steers & fattening cows | heifers | bulls | |:---------------|-----------:|--------------------------:|----------:|--------:| | Maldonado | 0.717 | 0.132 | 0.131 | 0.021 | | Treinta y Tres | 0.698 | 0.153 | 0.132 | 0.017 | | Rocha | 0.678 | 0.175 | 0.129 | 0.018 | | Florida | 0.677 | 0.149 | 0.157 | 0.017 | | Lavalleja | 0.673 | 0.178 | 0.131 | 0.018 | | Rivera | 0.67 | 0.167 | 0.146 | 0.016 | | Colonia | 0.657 | 0.183 | 0.149 | 0.012 | | San José | 0.652 | 0.171 | 0.165 | 0.011 | | Cerro Largo | 0.649 | 0.205 | 0.13 | 0.016 | | Durazno | 0.649 | 0.205 | 0.129 | 0.017 | | Salto | 0.646 | 0.196 | 0.14 | 0.018 | | Artigas | 0.644 | 0.211 | 0.129 | 0.015 | | Paysandú | 0.637 | 0.213 | 0.133 | 0.017 | | Tacuarembó | 0.62 | 0.219 | 0.145 | 0.016 | | Flores | 0.606 | 0.232 | 0.148 | 0.015 | | Canelones | 0.601 | 0.226 | 0.159 | 0.015 | | Río Negro | 0.583 | 0.262 | 0.142 | 0.013 | | Montevideo | 0.581 | 0.208 | 0.193 | 0.018 | | Soriano | 0.527 | 0.298 | 0.16 | 0.014 | ### Cross-check against the source ```python csv = cw.source_csv(2025, "datosanimalesdetallados.csv") beef = csv[csv["EspecieCodigo"] == "1"] src = cw.num(beef["AnimalesPorCategoriaPD_AD"]).groupby([beef["DepartamentoCodigo"], beef["CategoriaCodigo"]]).sum() cube = cat.set_index(["code", "cat_code"])["animals"] diff = (cube - src.reindex(cube.index)).abs().max() cw.check("2025 beef cattle by department × category: cube = CSV (largest difference)", int(diff), 0, source="datosanimalesdetallados.csv 2025, AnimalesPorCategoriaPD_AD") cw.check("2025 beef categories sum to the beef total in datosanimales", int(cat["animals"].sum()), 11_583_321, source="notebook national-herd: beef cattle 2025") ``` ```text PASS 2025 beef cattle by department × category: cube = CSV (largest difference): 0 vs 0 (exactly) — datosanimalesdetallados.csv 2025, AnimalesPorCategoriaPD_AD PASS 2025 beef categories sum to the beef total in datosanimales: 11,583,321 vs 11,583,321 (exactly) — notebook national-herd: beef cattle 2025 ``` The cube also materialises a composition at ingest, the derived metric `category_share_of_bovine`. Its denominator is a department's **whole** cattle herd, beef and dairy together (its shares sum to 1 across both species' categories), where ours is the beef herd alone. Put on its denominator, our numbers must reproduce it for every department and category, to the six decimals it keeps. ```python derived = cw.sparql(""" SELECT ?department ?category ?value WHERE { GRAPH ?g { ?d a cow:DerivedMetricObservation ; cow:year "2025"^^xsd:gYear ; cow:metric cow:metric_category_share_of_bovine ; cow:department ?department ; cow:animalCategory ?category ; cow:metricValue ?value . } } """) whole = allcat.assign(code=allcat["department"].map(cw.dept_code)).groupby("code")["animals"].sum() ours_all = allcat.assign(code=allcat["department"].map(cw.dept_code)) ours_all["share"] = ours_all["animals"] / ours_all["code"].map(whole) mine = ours_all.set_index(["code", "category"])["share"] theirs = derived.assign(code=derived["department"].map(cw.dept_code)).set_index(["code", "category"])["value"].astype(float) cw.check("derived rows cover every department × category", len(theirs), len(mine), source="cube derived metric") gap = float((theirs - mine.reindex(theirs.index)).abs().max()) cw.check("category_share_of_bovine (derived, 6 dp) = our shares on its denominator (largest gap)", round(gap, 7), 0.0, tol=5e-7, source="cow:metric_category_share_of_bovine, materialised at ingest") ``` ```text PASS derived rows cover every department × category: 304 vs 304 (exactly) — cube derived metric PASS category_share_of_bovine (derived, 6 dp) = our shares on its denominator (largest gap): 5e-07 vs 0 (within ±5e-07) — cow:metric_category_share_of_bovine, materialised at ingest ``` ```python east = share.iloc[0] west = share.sort_values("steers & fattening cows", ascending=False).iloc[0] # The sentence below says "east" and "west": hold it to that. EAST = {"Maldonado", "Rocha", "Treinta y Tres", "Lavalleja", "Cerro Largo"} WEST = {"Soriano", "Río Negro", "Colonia", "Paysandú", "San José"} cw.check("the most breeding-heavy department is in the east", east["name"] in EAST, True, source=f"{sorted(EAST)}") cw.check("the most finishing-heavy department is in the west", west["name"] in WEST, True, source=f"{sorted(WEST)}") cw.finding("headline", f"**{east['name']}** is the most breeding-heavy department: {east['breeding']:.1%} of its beef herd is " f"breeding cows and calves. **{west['name']}** leans hardest to finishing: " f"{west['steers & fattening cows']:.1%} steers and fattening cows. The east breeds; the west finishes.") ``` ```text PASS the most breeding-heavy department is in the east: True vs True (exactly) — ['Cerro Largo', 'Lavalleja', 'Maldonado', 'Rocha', 'Treinta y Tres'] PASS the most finishing-heavy department is in the west: True vs True (exactly) — ['Colonia', 'Paysandú', 'Río Negro', 'San José', 'Soriano'] ``` > **Finding.** **Maldonado** is the most breeding-heavy department: 71.7% of its beef herd is breeding cows and calves. **Soriano** leans hardest to finishing: 29.8% steers and fattening cows. The east breeds; the west finishes. ```python long = share.reset_index().melt(id_vars=["code", "name"], value_vars=["breeding", "heifers", "bulls", "steers & fattening cows"], var_name="group", value_name="share") order = share["name"].tolist() stack = alt.Chart(long, title=alt.Title("Beef herd composition by department, 2025", subtitle="share of beef cattle (PD_AD); departments ordered by breeding share")).mark_bar(height=14).encode( y=alt.Y("name:N", sort=order, title=None), x=alt.X("share:Q", stack="normalize", title=None, axis=alt.Axis(format=".0%")), color=alt.Color("group:N", scale=alt.Scale(domain=["breeding", "heifers", "bulls", "steers & fattening cows"], range=[cc.CATTLE, cc.SERIES[3], cc.MUTED, cc.SHEEP]), title=None), order=alt.Order("group_order:Q"), tooltip=["name:N", "group:N", alt.Tooltip("share:Q", format=".1%")], ).transform_calculate(group_order="indexof(['breeding','heifers','bulls','steers & fattening cows'], datum.group)").properties(width=500, height=380) cc.show(stack, "composition", alt_text="Stacked bars per department: eastern departments (Maldonado, Treinta y Tres, Rocha) have the largest breeding share; Soriano and Río Negro the largest share of steers.") ``` ![Stacked bars per department: eastern departments (Maldonado, Treinta y Tres, Rocha) have the largest breeding share; Soriano and Río Negro the largest share of steers.](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/composition.svg) Chart data and encoding: [charts/composition.vl.json](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/composition.vl.json) (Vega-Lite). ```python share["steers_per_breeding"] = share["steers & fattening cows"] / share["breeding"] cc.show(cc.choropleth(share.reset_index(), "steers_per_breeding", title="Steers and fattening cows per breeding animal, 2025", subtitle="(categories 3–6) ÷ (breeding cows + calves); higher = more finishing", legend="ratio", fmt=".2f"), "finishing-map", thumbnail=True, alt_text="Map: the finishing ratio is highest in the littoral west (Soriano, Río Negro) and lowest in Maldonado.") print(cc.map_credit()) ``` ![Map: the finishing ratio is highest in the littoral west (Soriano, Río Negro) and lowest in Maldonado.](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/finishing-map.svg) Chart data and encoding: [charts/finishing-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/finishing-map.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:---------------------------------------------------------------------------------------|--------------:|--------------:|:--------------|:---------------------------------------------------------------------| | every beef category maps to a group | 0 | 0 | exactly | the 9 beef categories | | 2025 beef cattle by department × category: cube = CSV (largest difference) | 0 | 0 | exactly | datosanimalesdetallados.csv 2025, AnimalesPorCategoriaPD_AD | | 2025 beef categories sum to the beef total in datosanimales | 1.15833e+07 | 1.15833e+07 | exactly | notebook national-herd: beef cattle 2025 | | derived rows cover every department × category | 304 | 304 | exactly | cube derived metric | | category_share_of_bovine (derived, 6 dp) = our shares on its denominator (largest gap) | 5e-07 | 0 | within ±5e-07 | cow:metric_category_share_of_bovine, materialised at ingest | | the most breeding-heavy department is in the east | 1 | 1 | exactly | ['Cerro Largo', 'Lavalleja', 'Maldonado', 'Rocha', 'Treinta y Tres'] | | the most finishing-heavy department is in the west | 1 | 1 | exactly | ['Colonia', 'Paysandú', 'Río Negro', 'San José', 'Soriano'] | ```text kind target rows \ 0 sparql uruguay-cows 304 1 sparql uruguay-cows 9 2 sparql uruguay-cows 304 first line 0 SELECT ?department ?species ?category (SUM(?n)... 1 SELECT DISTINCT ?category ?label 2 SELECT ?department ?category ?value ``` ```python cw.save() ``` --- ### How hard the land is stocked Finding: Uruguay carries 0.856 cattle per hectare of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, San José, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65. Page: https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/stocking-intensity.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.md # How hard the land is stocked **Answer.** Uruguay carries **0.856 cattle per hectare** of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, **San José**, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65. Notebook: https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/stocking-intensity.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## Findings - Uruguay carries **0.856 cattle per hectare** of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, **San José**, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65. - Density follows the sown pasture: across departments, Spearman ρ = **0.847** between cattle per hectare and the share of land under *praderas*. Nationally 72.4% of declared land is native grassland and only 6.9% sown pasture: intensity is a thin southern veneer. - Of 629 census areas with at least 100 livestock hectares, the densest is area **317003 in Canelones** at 8.33 cattle per hectare; the median area carries 0.91. ## The notebook Most of Uruguay's cattle graze *campo natural*, native grassland that has fed cattle since the 17th century. Where farmers have sown pastures (*praderas*) or improved the native grass, the land carries more animals. This notebook measures stocking density, cattle per hectare of livestock land, at two scales: the 19 departments and the 600-odd *áreas de enumeración*, DIEA's census areas, the finest grain DICOSE publishes. Two inputs, both from the declarations: cattle (beef + dairy, PD_AD) from `datosanimales.csv`, and *superficie ganadera*, the hectares a holder uses for livestock, from `datosgenerales.csv`. ```python # Setup. import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc names = cc.department_names() ``` ```python # The query: cattle and livestock hectares per census area, 2025. cattle = cw.sparql(""" SELECT ?department ?area (SUM(?n) AS ?cattle) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:enumerationArea ?area ; cow:species ?s ; cow:animalsCount ?n . VALUES ?s { } } } GROUP BY ?department ?area """) land = cw.sparql(""" SELECT ?department ?area (SUM(?ha) AS ?livestock_ha) (SUM(?lu) AS ?livestock_units) WHERE { GRAPH ?g { ?obs a cow:GeneralHoldingObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:enumerationArea ?area ; cow:livestockHectares ?ha ; cow:livestockUnits ?lu . } } GROUP BY ?department ?area """) ae = cattle.merge(land, on=["department", "area"], how="outer") ae["code"] = ae["department"].map(cw.dept_code) ae["area_code"] = ae["area"].map(cw.dept_code) ae["cattle"] = ae["cattle"].fillna(0).astype(int) for c in ("livestock_ha", "livestock_units"): ae[c] = ae[c].apply(lambda v: float(v) if v is not None and v == v else 0.0) print(f"{ae['area_code'].nunique()} census-area codes, {len(ae)} (department, area) cells") ``` ```text 635 census-area codes, 667 (department, area) cells ``` A census area can straddle a department line (the area follows the land; the department follows where the holder is registered), so we key on the pair. Area code `0` collects holdings DICOSE could not place in any area. ```python dept = ae.groupby("code")[["cattle", "livestock_ha", "livestock_units"]].sum().reset_index() dept["name"] = dept["code"].map(names) dept["density"] = dept["cattle"] / dept["livestock_ha"] dept = dept.sort_values("density", ascending=False) national = dept["cattle"].sum() / dept["livestock_ha"].sum() cc.show_table(dept[["name", "density", "cattle", "livestock_ha"]], floatfmt=",.3f", name="density-by-department") ``` | name | density | cattle | livestock_ha | |:---------------|----------:|:----------|:---------------| | San José | 1.67 | 541,254 | 324,103.300 | | Colonia | 1.553 | 537,066 | 345,775.100 | | Canelones | 1.391 | 338,601 | 243,465.000 | | Florida | 1.186 | 1,117,097 | 942,194.800 | | Soriano | 1.15 | 567,452 | 493,507.300 | | Flores | 1.005 | 409,429 | 407,511.500 | | Durazno | 0.97 | 952,171 | 981,607.200 | | Montevideo | 0.918 | 2,736 | 2,980.200 | | Río Negro | 0.875 | 549,369 | 627,763.500 | | Rivera | 0.83 | 639,917 | 770,887.200 | | Cerro Largo | 0.782 | 950,412 | 1,214,639.600 | | Lavalleja | 0.766 | 654,451 | 853,971.200 | | Rocha | 0.755 | 682,644 | 903,944.000 | | Tacuarembó | 0.751 | 1,061,136 | 1,413,868.000 | | Treinta y Tres | 0.725 | 584,734 | 806,167.600 | | Salto | 0.679 | 898,899 | 1,323,035.000 | | Paysandú | 0.679 | 801,512 | 1,180,985.200 | | Maldonado | 0.667 | 234,191 | 351,185.500 | | Artigas | 0.655 | 742,198 | 1,133,714.600 | ### Cross-check against the source ```python g = cw.source_csv(2025, "datosgenerales.csv") a = cw.source_csv(2025, "datosanimales.csv") src_ha = cw.num(g["SuperficieGanadera"]).groupby(g["DepartamentoCodigo"]).sum() bov = a[a["EspecieCodigo"].isin(["1", "11"])] src_cattle = cw.num(bov["AnimalesPorEspeciePD_AD"]).groupby(bov["DepartamentoCodigo"]).sum() d = dept.set_index("code") cw.check("livestock hectares per department: cube = CSV (largest difference, ha)", round(float((d["livestock_ha"] - src_ha.reindex(d.index)).abs().max()), 6), 0.0, source="datosgenerales.csv 2025, SuperficieGanadera") cw.check("cattle per department: cube = CSV (largest difference, heads)", int((d["cattle"] - src_cattle.reindex(d.index)).abs().max()), 0, source="datosanimales.csv 2025") cw.check("national livestock hectares, millions", round(dept["livestock_ha"].sum() / 1e6, 2), 14.32, tol=0.005, source="expedition 2026-07-05: 14.32M ha") cw.check("national density, cattle per livestock ha", round(national, 3), 0.856, tol=0.0005, source="expedition 2026-07-05: 0.856") cw.check("San José density", round(d.loc["16", "density"], 2), 1.67, tol=0.005, source="expedition 2026-07-05") # The cube also materialises this ratio at ingest (cow:metric_bovine_per_livestock_hectare, computed by cow-tools # from its own sums): all 19 departments must agree with ours. derived = cw.sparql(""" SELECT ?department ?value WHERE { GRAPH ?g { ?o a cow:DerivedMetricObservation ; cow:year "2025"^^xsd:gYear ; cow:metric cow:metric_bovine_per_livestock_hectare ; cow:department ?department ; cow:metricValue ?value } } """) derived["code"] = derived["department"].map(cw.dept_code) gap = (d["density"] - derived.set_index("code")["value"].astype(float).reindex(d.index)).abs().max() cw.check("all 19 densities = the cube's derived metric (largest gap)", round(float(gap), 6), 0.0, tol=1e-6, source="cow:metric_bovine_per_livestock_hectare, materialised at ingest") cw.check("Artigas density", round(d.loc["1", "density"], 4), 0.6547, tol=0.00005, source="the July expedition printed 0.66; the exact value is 0.6547, so that was a rounding slip") ``` ```text PASS livestock hectares per department: cube = CSV (largest difference, ha): 0 vs 0 (exactly) — datosgenerales.csv 2025, SuperficieGanadera PASS cattle per department: cube = CSV (largest difference, heads): 0 vs 0 (exactly) — datosanimales.csv 2025 PASS national livestock hectares, millions: 14.32 vs 14.32 (within ±0.005) — expedition 2026-07-05: 14.32M ha PASS national density, cattle per livestock ha: 0.856 vs 0.856 (within ±0.0005) — expedition 2026-07-05: 0.856 PASS San José density: 1.67 vs 1.67 (within ±0.005) — expedition 2026-07-05 ``` ```text PASS all 19 densities = the cube's derived metric (largest gap): 0 vs 0 (within ±1e-06) — cow:metric_bovine_per_livestock_hectare, materialised at ingest PASS Artigas density: 0.6547 vs 0.6547 (within ±5e-05) — the July expedition printed 0.66; the exact value is 0.6547, so that was a rounding slip ``` ```python cw.finding("headline", f"Uruguay carries **{national:.3f} cattle per hectare** of livestock land " f"({int(dept['cattle'].sum()):,} cattle on {dept['livestock_ha'].sum()/1e6:.2f} million ha). " f"The densest department, **{dept.iloc[0]['name']}**, carries {dept.iloc[0]['density']:.2f}; " f"the sparsest of the big grazing departments, {dept.query('livestock_ha > 500000').iloc[-1]['name']}, " f"{dept.query('livestock_ha > 500000').iloc[-1]['density']:.2f}.") ``` > **Finding.** Uruguay carries **0.856 cattle per hectare** of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, **San José**, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65. ```python cc.show(cc.choropleth(dept, "density", title="Cattle per hectare of livestock land, 2025", subtitle="beef + dairy (PD_AD) ÷ superficie ganadera", legend="cattle per ha", fmt=".2f", domain=[0, 1.8]), "density-map", thumbnail=True, alt_text="Map: stocking density is highest in the south-west (San José, Colonia, Canelones) and lowest in the north-west (Artigas, Salto).") print(cc.map_credit()) ``` ![Map: stocking density is highest in the south-west (San José, Colonia, Canelones) and lowest in the north-west (Artigas, Salto).](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-map.svg) Chart data and encoding: [charts/density-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-map.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ## Why: the sown pastures The land-use table says how each holding's land is used. Code `1`, *praderas artificiales permanentes*, is the sown, permanent pasture; code `8` is native grassland and stubble. The July 2026 expedition found the department ranking by density follows the share of sown pasture closely (Spearman ρ = 0.847). We recompute it. ```python # The query: hectares by land use per department, 2025. use = cw.sparql(""" SELECT ?department ?use (SUM(?ha) AS ?hectares) WHERE { GRAPH ?g { ?obs a cow:LandUseObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:landUse ?use ; cow:hectares ?ha . } } GROUP BY ?department ?use """) use["code"] = use["department"].map(cw.dept_code) use["use_code"] = use["use"].map(cw.dept_code) use["hectares"] = use["hectares"].astype(float) mix = use.pivot_table(index="code", columns="use_code", values="hectares", aggfunc="sum").fillna(0) shares = mix.div(mix.sum(axis=1), axis=0) dept = dept.merge(shares[["1", "8"]].rename(columns={"1": "praderas", "8": "campo_natural"}), left_on="code", right_index=True) nat = mix.sum() / mix.sum().sum() rho = dept[["density", "praderas"]].rank().corr().iloc[0, 1] cw.check("national share of campo natural", round(nat["8"], 3), 0.724, tol=0.0005, source="expedition 2026-07-05: 72.4%") cw.check("national share of praderas", round(nat["1"], 3), 0.069, tol=0.0005, source="expedition 2026-07-05: 6.9%") cw.check("Spearman ρ, density vs praderas share", round(rho, 3), 0.847, tol=0.0005, source="expedition 2026-07-05") cw.finding("pastures", f"Density follows the sown pasture: across departments, Spearman ρ = **{rho:.3f}** between cattle per " f"hectare and the share of land under *praderas*. Nationally {nat['8']:.1%} of declared land is native " f"grassland and only {nat['1']:.1%} sown pasture: intensity is a thin southern veneer.") ``` ```text PASS national share of campo natural: 0.724 vs 0.724 (within ±0.0005) — expedition 2026-07-05: 72.4% PASS national share of praderas: 0.069 vs 0.069 (within ±0.0005) — expedition 2026-07-05: 6.9% PASS Spearman ρ, density vs praderas share: 0.847 vs 0.847 (within ±0.0005) — expedition 2026-07-05 ``` > **Finding.** Density follows the sown pasture: across departments, Spearman ρ = **0.847** between cattle per hectare and the share of land under *praderas*. Nationally 72.4% of declared land is native grassland and only 6.9% sown pasture: intensity is a thin southern veneer. ```python pts = alt.Chart(dept, title=alt.Title("Density follows the sown pasture", subtitle="one point per department, 2025")).mark_point(filled=True, size=70, color=cc.CATTLE).encode( x=alt.X("praderas:Q", title="share of land under sown pasture (praderas)", axis=alt.Axis(format=".0%")), y=alt.Y("density:Q", title="cattle per livestock hectare"), tooltip=["name:N", alt.Tooltip("praderas:Q", format=".1%"), alt.Tooltip("density:Q", format=".2f")], ) # Label the spread-out departments; the crowded corner is in the tooltip and the table above. labels = alt.Chart(dept).transform_filter( "datum.praderas > 0.09 || indexof(['Artigas', 'Durazno', 'Rivera'], datum.name) >= 0" ).mark_text(align="left", dx=6, dy=-4, fontSize=11).encode(x="praderas:Q", y="density:Q", text="name:N") cc.show((pts + labels).properties(width=520, height=320), "density-vs-praderas", alt_text="Scatter: departments with more sown pasture carry more cattle per hectare; San José and Colonia top right, Artigas and Salto bottom left.") ``` ![Scatter: departments with more sown pasture carry more cattle per hectare; San José and Colonia top right, Artigas and Salto bottom left.](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-vs-praderas.svg) Chart data and encoding: [charts/density-vs-praderas.vl.json](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-vs-praderas.vl.json) (Vega-Lite). ## The census areas Down at the census areas the range is wide. Each dot is one area in its department (areas with under 100 livestock hectares are left out: a few feedlots and dairy yards on tiny land bases would otherwise dominate the scale; they are listed below). ```python # An area can straddle a department line: sum it across departments, and file it under the department # holding most of its livestock land. cells = ae[ae["area_code"] != "0"] home = cells.sort_values("livestock_ha").groupby("area_code").tail(1).set_index("area_code")["code"] areas = cells.groupby("area_code")[["cattle", "livestock_ha"]].sum() areas = areas[areas["livestock_ha"] >= 100].reset_index() areas["name"] = areas["area_code"].map(home).map(names) areas["density"] = areas["cattle"] / areas["livestock_ha"] small = cells.groupby("area_code")[["cattle", "livestock_ha"]].sum().query("livestock_ha < 100 and cattle > 0") order = dept.sort_values("density", ascending=False)["name"].tolist() strip = alt.Chart(areas, title=alt.Title("Cattle per livestock hectare, by census area, 2025", subtitle=f"{len(areas)} areas with at least 100 livestock ha; departments ordered by overall density")).mark_tick( thickness=2, size=14, color=cc.CATTLE, opacity=0.7).encode( x=alt.X("density:Q", title="cattle per livestock hectare", scale=alt.Scale(domain=[0, 4], clamp=True)), y=alt.Y("name:N", sort=order, title=None), tooltip=["name:N", alt.Tooltip("area_code:N", title="census area"), alt.Tooltip("density:Q", format=".2f"), alt.Tooltip("cattle:Q", format=","), alt.Tooltip("livestock_ha:Q", format=",.0f")], ).properties(width=520, height=420) cc.show(strip, "areas-strip", alt_text="Strip plot: each department's census areas as ticks along a density axis; the south-west spreads furthest right.") top = areas.sort_values("density", ascending=False).head(5) cc.show_table(top[["name", "area_code", "density", "cattle", "livestock_ha"]], floatfmt=",.2f", name="densest-areas") print(f"{cells['area_code'].nunique()} census-area codes carry holdings (code 0, unplaced, excluded); " f"{(cells.groupby('area_code')['code'].nunique() > 1).sum()} of them straddle a department line.") print(f"{len(small)} areas with cattle on under 100 livestock ha were left out of the strip plot.") ``` ![Strip plot: each department's census areas as ticks along a density axis; the south-west spreads furthest right.](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/areas-strip.svg) Chart data and encoding: [charts/areas-strip.vl.json](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/areas-strip.vl.json) (Vega-Lite). | name | area_code | density | cattle | livestock_ha | |:----------|------------:|----------:|:---------|:---------------| | Canelones | 317003 | 8.33 | 11,589 | 1,391.20 | | San José | 1607005 | 6.38 | 4,879 | 765.10 | | Canelones | 305004 | 5.59 | 4,312 | 771.90 | | Soriano | 1704001 | 4.76 | 18,400 | 3,862.00 | | Florida | 805004 | 4.62 | 20,074 | 4,344.10 | ```text 634 census-area codes carry holdings (code 0, unplaced, excluded); 14 of them straddle a department line. 5 areas with cattle on under 100 livestock ha were left out of the strip plot. ``` ```python cw.check("every area cell is inside a department", int(ae["code"].isna().sum()), 0, source="cube") cw.finding("areas", f"Of {len(areas)} census areas with at least 100 livestock hectares, the densest is area " f"**{top.iloc[0]['area_code']} in {top.iloc[0]['name']}** at {top.iloc[0]['density']:.2f} cattle per hectare; " f"the median area carries {areas['density'].median():.2f}.") ``` ```text PASS every area cell is inside a department: 0 vs 0 (exactly) — cube ``` > **Finding.** Of 629 census areas with at least 100 livestock hectares, the densest is area **317003 in Canelones** at 8.33 cattle per hectare; the median area carries 0.91. ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:-----------------------------------------------------------------------|------:|-----------:|:---------------|:-----------------------------------------------------------------------------------------| | livestock hectares per department: cube = CSV (largest difference, ha) | 0 | 0 | exactly | datosgenerales.csv 2025, SuperficieGanadera | | cattle per department: cube = CSV (largest difference, heads) | 0 | 0 | exactly | datosanimales.csv 2025 | | national livestock hectares, millions | 14.32 | 14.32 | within ±0.005 | expedition 2026-07-05: 14.32M ha | | national density, cattle per livestock ha | 0.86 | 0.86 | within ±0.0005 | expedition 2026-07-05: 0.856 | | San José density | 1.67 | 1.67 | within ±0.005 | expedition 2026-07-05 | | all 19 densities = the cube's derived metric (largest gap) | 0 | 0 | within ±1e-06 | cow:metric_bovine_per_livestock_hectare, materialised at ingest | | Artigas density | 0.65 | 0.65 | within ±5e-05 | the July expedition printed 0.66; the exact value is 0.6547, so that was a rounding slip | | national share of campo natural | 0.72 | 0.72 | within ±0.0005 | expedition 2026-07-05: 72.4% | | national share of praderas | 0.07 | 0.07 | within ±0.0005 | expedition 2026-07-05: 6.9% | | Spearman ρ, density vs praderas share | 0.85 | 0.85 | within ±0.0005 | expedition 2026-07-05 | | every area cell is inside a department | 0 | 0 | exactly | cube | ```text kind target rows \ 0 sparql uruguay-cows 660 1 sparql uruguay-cows 667 2 sparql uruguay-cows 19 3 sparql uruguay-cows 152 first line 0 SELECT ?department ?area (SUM(?n) AS ?cattle) 1 SELECT ?department ?area (SUM(?ha) AS ?livesto... 2 SELECT ?department ?value 3 SELECT ?department ?use (SUM(?ha) AS ?hectares) ``` ```python cw.save() ``` --- ### One year on, 2024 to 2025 Finding: Between the 2024 and 2025 declarations Uruguay gained 127,121 cattle (+1.05%) and lost 621,595 sheep (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands. Page: https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/year-over-year/year-over-year.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.md # One year on, 2024 to 2025 **Answer.** Between the 2024 and 2025 declarations Uruguay gained **127,121 cattle** (+1.05%) and lost **621,595 sheep** (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands. Notebook: https://cow-tools.sophia-labs.com/notebooks/year-over-year/year-over-year.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## Findings - Between the 2024 and 2025 declarations Uruguay gained **127,121 cattle** (+1.05%) and lost **621,595 sheep** (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands. - Growth came from the north and centre (**Salto** +5.9%, Durazno +5.8%, Rivera +5.2%); the south and east shrank (**Canelones** -4.8%, Treinta y Tres -4.6%). ## The notebook Two declarations, a year apart. Before comparing them we read what the cube says about its own quality: cow-tools records every warning raised at ingest as a `cow:QualityWarning` in the year's quality graph. A comparison that leans on a dimension a warning touches must say so, or not be made. ```python # Setup. import re import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc names = cc.department_names() ``` ## First, the warnings ```python # The query: every quality report and warning the cube recorded, per year. reports = cw.sparql(""" SELECT ?year ?passed ?blocking ?warnings WHERE { GRAPH ?g { ?r a cow:QualityReport ; cow:sourceYear ?year ; cow:passed ?passed ; cow:blockingViolationCount ?blocking ; cow:warningCount ?warnings } } ORDER BY ?year """) warnings = cw.sparql(""" SELECT ?year ?message WHERE { GRAPH ?g { ?w a cow:QualityWarning ; cow:sourceYear ?year ; cow:message ?message } } ORDER BY ?year ?message """, allow_empty=True) cc.show_table(reports, name="quality-reports") cc.show_table(warnings, name="quality-warnings") ``` | year | passed | blocking | warnings | |:-------|:---------|-----------:|-----------:| | 2,024 | True | 0 | 1 | | 2,025 | True | 0 | 3 | | year | message | |:-------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 2,024 | optional source file not found: Codigos de areas de enumeracion | | 2,025 | codelist 'scheme_mgap_production_types' has no table for snapshot year 2025; borrowed 9 concept(s) from snapshot year 2024 (explicit cross-year borrow, recorded as ) | | 2,025 | optional source file not found: Codigos de areas de enumeracion | | 2,025 | optional source file not found: Codigos de tipos de produccion MGAP | ```python cw.check("both years passed their quality gate", bool(reports["passed"].all()), True, source="cow:QualityReport") cw.check("no blocking violations in either year", int(reports["blocking"].sum()), 0, source="cow:QualityReport") cw.check("every counted warning is recorded", int(reports["warnings"].sum()), len(warnings), source="cow:warningCount vs cow:QualityWarning rows") ``` ```text PASS both years passed their quality gate: True vs True (exactly) — cow:QualityReport PASS no blocking violations in either year: 0 vs 0 (exactly) — cow:QualityReport PASS every counted warning is recorded: 4 vs 4 (exactly) — cow:warningCount vs cow:QualityWarning rows ``` Each warning names what it touches: a codelist borrowed from another year, or an optional source file missing from a package. This comparison uses three things: the **department** and **species** codelists and the **datosanimales** table. We collect what the warnings touch and refuse to go on if any of the three is among them. ```python touched = set() for msg in warnings["message"]: touched |= set(re.findall(r"codelist '([^']+)'", msg)) touched |= set(m.strip() for m in re.findall(r"optional source file not found: (.+)", msg)) print("touched by a warning:", sorted(touched) or "nothing") uses = {"departments", "species", "datos_animales", "Datos animales"} hit = sorted(t for t in touched if any(u.lower().replace("_", " ") in t.lower().replace("_", " ") for u in uses)) cw.check("no warning touches the dimensions this comparison uses", hit, [], source=f"uses: {sorted(uses)}") ``` ```text touched by a warning: ['Codigos de areas de enumeracion', 'Codigos de tipos de produccion MGAP', 'scheme_mgap_production_types'] PASS no warning touches the dimensions this comparison uses: [] vs [] (exactly) — uses: ['Datos animales', 'datos_animales', 'departments', 'species'] ``` ## Cattle, sheep and holders, both years ```python # The query: stock and holders per department, species and year. q = cw.sparql(""" SELECT ?year ?department ?species (SUM(?n) AS ?animals) (SUM(?h) AS ?holders) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year ?year ; cow:department ?department ; cow:species ?species ; cow:animalsCount ?n ; cow:holdersCount ?h . } } GROUP BY ?year ?department ?species """) q["code"] = q["department"].map(cw.dept_code) q["sp"] = q["species"].map(cw.dept_code) q["kind"] = q["sp"].map({"1": "cattle", "11": "cattle", "2": "sheep"}) nat = q.dropna(subset=["kind"]).groupby(["kind", "year"])["animals"].sum().unstack() beef_holders = q.query("sp == '1'").groupby("year")["holders"].sum() nat ``` ```text year 2024 2025 kind cattle 12138148 12265269 sheep 5420661 4799066 ``` ```python for year in (2024, 2025): csv = cw.source_csv(year, "datosanimales.csv") beef = csv[csv["EspecieCodigo"] == "1"] cw.check(f"{year} holders declaring beef cattle: cube = CSV", int(beef_holders[year]), int(cw.num(beef["CantidadTenedoresPorEspecie"]).sum()), source=f"datosanimales.csv {year}, CantidadTenedoresPorEspecie") change = nat[2025] / nat[2024] - 1 cw.check("cattle 2024 → 2025", round(change["cattle"], 4), 0.0105, tol=0.00005, source="expedition 2026-07-05: +1.05%") cw.finding("headline", f"Between the 2024 and 2025 declarations Uruguay gained **{int(nat.loc['cattle', 2025] - nat.loc['cattle', 2024]):,} cattle** " f"({change['cattle']:+.2%}) and lost **{int(nat.loc['sheep', 2024] - nat.loc['sheep', 2025]):,} sheep** " f"({change['sheep']:+.2%}), while the number of holders declaring beef cattle went from " f"{int(beef_holders[2024]):,} to {int(beef_holders[2025]):,} ({beef_holders[2025]/beef_holders[2024]-1:+.1%}): " f"more cattle, fewer hands.") cw.check("fewer holders declared beef cattle in 2025 (so 'fewer hands' holds)", bool(beef_holders[2025] < beef_holders[2024]), True, source="the two numbers above") ``` ```text PASS 2024 holders declaring beef cattle: cube = CSV: 61,561 vs 61,561 (exactly) — datosanimales.csv 2024, CantidadTenedoresPorEspecie PASS 2025 holders declaring beef cattle: cube = CSV: 59,121 vs 59,121 (exactly) — datosanimales.csv 2025, CantidadTenedoresPorEspecie PASS cattle 2024 → 2025: 0.0105 vs 0.0105 (within ±5e-05) — expedition 2026-07-05: +1.05% ``` > **Finding.** Between the 2024 and 2025 declarations Uruguay gained **127,121 cattle** (+1.05%) and lost **621,595 sheep** (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands. ```text PASS fewer holders declared beef cattle in 2025 (so 'fewer hands' holds): True vs True (exactly) — the two numbers above ``` ## Department by department ```python cat = q.query("kind == 'cattle'").groupby(["code", "year"])["animals"].sum().unstack() cat.columns = ["cattle_2024", "cattle_2025"] cat["change"] = cat["cattle_2025"] / cat["cattle_2024"] - 1 cat = cat.reset_index() cat["name"] = cat["code"].map(names) cat = cat.sort_values("change", ascending=False) c = cat.set_index("name")["change"] for name, expected in [("Salto", 0.059), ("Durazno", 0.058), ("Rivera", 0.052), ("Canelones", -0.048), ("Treinta y Tres", -0.046)]: cw.check(f"{name} cattle 2024 → 2025", round(c[name], 3), expected, tol=0.0005, source="expedition 2026-07-05") cc.show_table(cat[["name", "cattle_2024", "cattle_2025", "change"]], floatfmt="+.3f", name="cattle-change") ``` ```text PASS Salto cattle 2024 → 2025: 0.059 vs 0.059 (within ±0.0005) — expedition 2026-07-05 PASS Durazno cattle 2024 → 2025: 0.058 vs 0.058 (within ±0.0005) — expedition 2026-07-05 PASS Rivera cattle 2024 → 2025: 0.052 vs 0.052 (within ±0.0005) — expedition 2026-07-05 PASS Canelones cattle 2024 → 2025: -0.048 vs -0.048 (within ±0.0005) — expedition 2026-07-05 PASS Treinta y Tres cattle 2024 → 2025: -0.046 vs -0.046 (within ±0.0005) — expedition 2026-07-05 ``` | name | cattle_2024 | cattle_2025 | change | |:---------------|:--------------|:--------------|---------:| | Salto | 849,010 | 898,899 | 0.059 | | Durazno | 900,286 | 952,171 | 0.058 | | Rivera | 608,407 | 639,917 | 0.052 | | Flores | 393,191 | 409,429 | 0.041 | | Tacuarembó | 1,034,575 | 1,061,136 | 0.026 | | Florida | 1,095,226 | 1,117,097 | 0.02 | | Artigas | 730,165 | 742,198 | 0.016 | | Maldonado | 230,533 | 234,191 | 0.016 | | Lavalleja | 644,438 | 654,451 | 0.016 | | Montevideo | 2,699 | 2,736 | 0.014 | | Soriano | 570,050 | 567,452 | -0.005 | | Cerro Largo | 957,379 | 950,412 | -0.007 | | Rocha | 688,313 | 682,644 | -0.008 | | Paysandú | 809,798 | 801,512 | -0.01 | | Río Negro | 555,782 | 549,369 | -0.012 | | San José | 548,346 | 541,254 | -0.013 | | Colonia | 551,213 | 537,066 | -0.026 | | Treinta y Tres | 613,051 | 584,734 | -0.046 | | Canelones | 355,686 | 338,601 | -0.048 | ```python # The sentence below names regions: hold it to them. NORTH_CENTRE = {"Artigas", "Salto", "Rivera", "Tacuarembó", "Paysandú", "Durazno", "Cerro Largo", "Flores"} SOUTH_EAST = {"Canelones", "Montevideo", "Maldonado", "Rocha", "Treinta y Tres", "Lavalleja", "San José", "Colonia"} cw.check("the three fastest growers are in the north and centre", set(cat["name"].head(3)) <= NORTH_CENTRE, True, source=str(sorted(NORTH_CENTRE))) cw.check("the two steepest declines are in the south and east", set(cat["name"].tail(2)) <= SOUTH_EAST, True, source=str(sorted(SOUTH_EAST))) cw.finding("where", f"Growth came from the north and centre (**{cat.iloc[0]['name']}** {cat.iloc[0]['change']:+.1%}, " f"{cat.iloc[1]['name']} {cat.iloc[1]['change']:+.1%}, {cat.iloc[2]['name']} {cat.iloc[2]['change']:+.1%}); " f"the south and east shrank (**{cat.iloc[-1]['name']}** {cat.iloc[-1]['change']:+.1%}, " f"{cat.iloc[-2]['name']} {cat.iloc[-2]['change']:+.1%}).") ``` ```text PASS the three fastest growers are in the north and centre: True vs True (exactly) — ['Artigas', 'Cerro Largo', 'Durazno', 'Flores', 'Paysandú', 'Rivera', 'Salto', 'Tacuarembó'] PASS the two steepest declines are in the south and east: True vs True (exactly) — ['Canelones', 'Colonia', 'Lavalleja', 'Maldonado', 'Montevideo', 'Rocha', 'San José', 'Treinta y Tres'] ``` > **Finding.** Growth came from the north and centre (**Salto** +5.9%, Durazno +5.8%, Rivera +5.2%); the south and east shrank (**Canelones** -4.8%, Treinta y Tres -4.6%). ```python cc.show(cc.choropleth(cat, "change", title="Change in cattle, 2024 → 2025", subtitle="beef + dairy, PD_AD; blue is growth, brown is decline", legend="change", fmt="+.1%", diverging=True), "cattle-change-map", thumbnail=True, alt_text="Diverging map: the north and centre (Salto, Durazno, Rivera) gained the most cattle; Canelones and Treinta y Tres lost the most.") print(cc.map_credit()) ``` ![Diverging map: the north and centre (Salto, Durazno, Rivera) gained the most cattle; Canelones and Treinta y Tres lost the most.](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-change-map.svg) Chart data and encoding: [charts/cattle-change-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-change-map.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ### The same change as a slope chart Each line is a department, from its 2024 to its 2025 herd (log scale, so a line's slope is its percentage change whatever the herd's size). ```python slope = cat.melt(id_vars=["name", "change"], value_vars=["cattle_2024", "cattle_2025"], var_name="year", value_name="cattle") slope["year"] = slope["year"].str[-4:] slope["direction"] = slope["change"].map(lambda v: "grew" if v > 0 else "shrank") base = alt.Chart(slope).encode( x=alt.X("year:N", title=None, axis=alt.Axis(labelAngle=0)), y=alt.Y("cattle:Q", scale=alt.Scale(type="log"), title="cattle (log scale)", axis=alt.Axis(format="~s")), color=alt.Color("direction:N", scale=alt.Scale(domain=["grew", "shrank"], range=[cc.CATTLE, cc.FALL]), title=None), detail="name:N", tooltip=["name:N", alt.Tooltip("cattle:Q", format=","), alt.Tooltip("change:Q", format="+.1%")], ) lines = base.mark_line(point=True) lab = alt.Chart(slope).transform_filter("datum.year == '2025'").mark_text(align="left", dx=6, fontSize=10).encode( x=alt.X("year:N"), y=alt.Y("cattle:Q", scale=alt.Scale(type="log")), text="name:N") cc.show((lines + lab).properties(width=260, height=440, title=alt.Title("Cattle by department, 2024 → 2025")), "cattle-slope", alt_text="Slope chart: most department lines rise gently; Canelones and Treinta y Tres fall.") ``` ![Slope chart: most department lines rise gently; Canelones and Treinta y Tres fall.](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-slope.svg) Chart data and encoding: [charts/cattle-slope.vl.json](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-slope.vl.json) (Vega-Lite). ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:--------------------------------------------------------------------|:-------|:-----------|:---------------|:--------------------------------------------------------------------------------------------------------| | both years passed their quality gate | True | True | exactly | cow:QualityReport | | no blocking violations in either year | 0 | 0 | exactly | cow:QualityReport | | every counted warning is recorded | 4 | 4 | exactly | cow:warningCount vs cow:QualityWarning rows | | no warning touches the dimensions this comparison uses | [] | [] | exactly | uses: ['Datos animales', 'datos_animales', 'departments', 'species'] | | 2024 holders declaring beef cattle: cube = CSV | 61561 | 61561 | exactly | datosanimales.csv 2024, CantidadTenedoresPorEspecie | | 2025 holders declaring beef cattle: cube = CSV | 59121 | 59121 | exactly | datosanimales.csv 2025, CantidadTenedoresPorEspecie | | cattle 2024 → 2025 | 0.0105 | 0.0105 | within ±5e-05 | expedition 2026-07-05: +1.05% | | fewer holders declared beef cattle in 2025 (so 'fewer hands' holds) | True | True | exactly | the two numbers above | | Salto cattle 2024 → 2025 | 0.059 | 0.059 | within ±0.0005 | expedition 2026-07-05 | | Durazno cattle 2024 → 2025 | 0.058 | 0.058 | within ±0.0005 | expedition 2026-07-05 | | Rivera cattle 2024 → 2025 | 0.052 | 0.052 | within ±0.0005 | expedition 2026-07-05 | | Canelones cattle 2024 → 2025 | -0.048 | -0.048 | within ±0.0005 | expedition 2026-07-05 | | Treinta y Tres cattle 2024 → 2025 | -0.046 | -0.046 | within ±0.0005 | expedition 2026-07-05 | | the three fastest growers are in the north and centre | True | True | exactly | ['Artigas', 'Cerro Largo', 'Durazno', 'Flores', 'Paysandú', 'Rivera', 'Salto', 'Tacuarembó'] | | the two steepest declines are in the south and east | True | True | exactly | ['Canelones', 'Colonia', 'Lavalleja', 'Maldonado', 'Montevideo', 'Rocha', 'San José', 'Treinta y Tres'] | ```text kind target rows \ 0 sparql uruguay-cows 2 1 sparql uruguay-cows 4 2 sparql uruguay-cows 228 first line 0 SELECT ?year ?passed ?blocking ?warnings 1 SELECT ?year ?message 2 SELECT ?year ?department ?species (SUM(?n) AS ... ``` ```python cw.save() ``` --- ### The herd ledger Finding: Uruguay's cattle books balance only if 2,300,543 head left the farms between the 2024 and 2025 declarations: 18.95% of the opening herd. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121). Page: https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/herd-ledger/herd-ledger.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.md # The herd ledger **Answer.** Uruguay's cattle books balance only if **2,300,543 head left the farms** between the 2024 and 2025 declarations: **18.95% of the opening herd**. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121). Notebook: https://cow-tools.sophia-labs.com/notebooks/herd-ledger/herd-ledger.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## Findings - Uruguay's cattle books balance only if **2,300,543 head left the farms** between the 2024 and 2025 declarations: **18.95% of the opening herd**. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121). - The July 2026 expedition's figure for Rocha (21.4%) carried the all-species bug; species-honest, Rocha's cattle offtake is **25.4%** of its opening herd. - By department the books run from **Treinta y Tres**, which shipped out 26.2% of its opening herd, to San José, 14.2%. Montevideo (a few thousand head) is left out of the extremes. ## The notebook A herd can be kept like a set of books. Opening stock, plus calves born, minus animals that died, minus animals slaughtered for the farm's own table, should equal closing stock, *unless animals left*. Whatever is left over is **offtake**: cattle sold to the meat-packing plants or exported on the hoof. DICOSE does not publish slaughter in this dataset, but it does publish the other four lines, so the fifth can be inferred. offtake = births − deaths − own consumption − (closing stock − opening stock) Opening stock is the 2024 declaration (30 June 2024); closing stock is the 2025 one; the flows (births, deaths, consumption) are those declared in 2025 for the year in between. This is the analysis that caught cow-tools out in July 2026. Births are only declared for cattle, but deaths and consumption are declared for every species; adding the sheep's deaths to the cattle's books made the extraction rate look 30% too low. The curated metrics are now species-honest (`bovine_births_count` and friends), and this notebook keeps to cattle by construction: species `1` and `11` only. ```python # Setup. import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc names = cc.department_names() ``` ```python # The query: cattle stock and flows per department, both years. q = cw.sparql(""" SELECT ?year ?department (SUM(?n) AS ?stock) (SUM(?b) AS ?births) (SUM(?d) AS ?deaths) (SUM(?c) AS ?consumption) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year ?year ; cow:department ?department ; cow:species ?s ; cow:animalsCount ?n . VALUES ?s { } OPTIONAL { ?obs cow:birthsCount ?b } OPTIONAL { ?obs cow:deathsCount ?d } OPTIONAL { ?obs cow:consumptionCount ?c } } } GROUP BY ?year ?department """) q["code"] = q["department"].map(cw.dept_code) for c in ("births", "deaths", "consumption"): q[c] = q[c].fillna(0).astype(int) n = q.groupby("year")[["stock", "births", "deaths", "consumption"]].sum() n ``` ```text stock births deaths consumption year 2024 12138148 2364279 264496 23069 2025 12265269 2697988 247498 22826 ``` ```python opening, closing = int(n.loc[2024, "stock"]), int(n.loc[2025, "stock"]) b, d, c = (int(n.loc[2025, k]) for k in ("births", "deaths", "consumption")) offtake = b - d - c - (closing - opening) rate = offtake / opening ledger = pd.DataFrame([ ("opening stock, 30 June 2024", opening), ("+ calves born", b), ("− deaths", -d), ("− slaughtered for own consumption", -c), ("− closing stock, 30 June 2025", -closing), ("= offtake (left the farms)", offtake), ], columns=["line", "head"]) cc.show_table(ledger, name="ledger") ``` | line | head | |:----------------------------------|:------------| | opening stock, 30 June 2024 | 12,138,148 | | + calves born | 2,697,988 | | − deaths | -247,498 | | − slaughtered for own consumption | -22,826 | | − closing stock, 30 June 2025 | -12,265,269 | | = offtake (left the farms) | 2,300,543 | ### Cross-check against the source, and against the July oracle ```python for year in (2024, 2025): csv = cw.source_csv(year, "datosanimales.csv") bov = csv[csv["EspecieCodigo"].isin(["1", "11"])] for col, key in [("AnimalesPorEspeciePD_AD", "stock"), ("AnimalesPorEspecieNacimientosPD_AD", "births"), ("AnimalesPorEspecieMortandadPD_AD", "deaths"), ("AnimalesPorEspecieConsumoPD_AD", "consumption")]: cw.check(f"{year} cattle {key}: cube = CSV", int(n.loc[year, key]), int(cw.num(bov[col]).sum()), source=f"datosanimales.csv {year}, {col}") cw.check("offtake 2024 → 2025, head", offtake, 2_300_543, source="cow-tools WP-0 oracle (e), 2026-07-06") cw.check("extraction rate", round(rate, 4), 0.1895, tol=0.00005, source="cow-tools WP-0 oracle (e): 18.95%") ``` ```text PASS 2024 cattle stock: cube = CSV: 12,138,148 vs 12,138,148 (exactly) — datosanimales.csv 2024, AnimalesPorEspeciePD_AD PASS 2024 cattle births: cube = CSV: 2,364,279 vs 2,364,279 (exactly) — datosanimales.csv 2024, AnimalesPorEspecieNacimientosPD_AD PASS 2024 cattle deaths: cube = CSV: 264,496 vs 264,496 (exactly) — datosanimales.csv 2024, AnimalesPorEspecieMortandadPD_AD PASS 2024 cattle consumption: cube = CSV: 23,069 vs 23,069 (exactly) — datosanimales.csv 2024, AnimalesPorEspecieConsumoPD_AD PASS 2025 cattle stock: cube = CSV: 12,265,269 vs 12,265,269 (exactly) — datosanimales.csv 2025, AnimalesPorEspeciePD_AD PASS 2025 cattle births: cube = CSV: 2,697,988 vs 2,697,988 (exactly) — datosanimales.csv 2025, AnimalesPorEspecieNacimientosPD_AD ``` ```text PASS 2025 cattle deaths: cube = CSV: 247,498 vs 247,498 (exactly) — datosanimales.csv 2025, AnimalesPorEspecieMortandadPD_AD PASS 2025 cattle consumption: cube = CSV: 22,826 vs 22,826 (exactly) — datosanimales.csv 2025, AnimalesPorEspecieConsumoPD_AD PASS offtake 2024 → 2025, head: 2,300,543 vs 2,300,543 (exactly) — cow-tools WP-0 oracle (e), 2026-07-06 PASS extraction rate: 0.1895 vs 0.1895 (within ±5e-05) — cow-tools WP-0 oracle (e): 18.95% ``` A sanity bound from outside the dataset: the July 2026 expedition set this against INAC's figures for cattle slaughtered plus cattle exported live, roughly 2.2 to 2.5 million head a year. The inferred offtake sits inside that range: the declarations are honest enough that a stranger's arithmetic recovers the country's actual metabolism. ```python cw.finding("headline", f"Uruguay's cattle books balance only if **{offtake:,} head left the farms** between the 2024 and 2025 " f"declarations: **{rate:.2%} of the opening herd**. Calves born ({b:,}) outran deaths ({d:,}), home slaughter " f"({c:,}) and the herd's own growth ({closing - opening:+,}).") ``` > **Finding.** Uruguay's cattle books balance only if **2,300,543 head left the farms** between the 2024 and 2025 declarations: **18.95% of the opening herd**. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121). ```python water = pd.DataFrame([ ("opening 2024", 0, opening, "stock"), ("births", opening, opening + b, "in"), ("deaths", opening + b - d, opening + b, "out"), ("own consumption", opening + b - d - c, opening + b - d, "out"), ("offtake", closing, opening + b - d - c, "out"), ("closing 2025", 0, closing, "stock"), ], columns=["step", "start", "end", "kind"]) water["order"] = range(len(water)) wf = alt.Chart(water, title=alt.Title("Uruguay's cattle ledger, 30 June 2024 → 30 June 2025", subtitle="head of cattle (beef + dairy); offtake is inferred")).mark_bar(size=34).encode( x=alt.X("step:N", sort=alt.SortField("order"), title=None, axis=alt.Axis(labelAngle=0)), y=alt.Y("start:Q", title="head", axis=alt.Axis(format="~s"), scale=alt.Scale(zero=False, domain=[9_000_000, 15_500_000])), y2="end:Q", color=alt.Color("kind:N", scale=alt.Scale(domain=["stock", "in", "out"], range=[cc.CATTLE, cc.DAIRY, cc.SHEEP]), title=None), tooltip=["step:N", alt.Tooltip("start:Q", format=","), alt.Tooltip("end:Q", format=",")], ).properties(width=540, height=300) cc.show(wf, "ledger-waterfall", alt_text="Waterfall: 12.14 million opening stock, plus 2.70 million births, minus small deaths and home slaughter, minus 2.30 million offtake, gives 12.27 million closing stock.") ``` ![Waterfall: 12.14 million opening stock, plus 2.70 million births, minus small deaths and home slaughter, minus 2.30 million offtake, gives 12.27 million closing stock.](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/ledger-waterfall.svg) Chart data and encoding: [charts/ledger-waterfall.vl.json](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/ledger-waterfall.vl.json) (Vega-Lite). ## Department by department The same books per department. A department's offtake also includes cattle sold to *other departments* (store calves going west to be finished), so a breeding department's "extraction" is high and a finishing department's low. That is the herd-structure notebook's story told in flows. ```python dep = q.pivot_table(index="code", columns="year", values=["stock", "births", "deaths", "consumption"]) dd = pd.DataFrame({ "opening": dep[("stock", 2024)], "closing": dep[("stock", 2025)], "births": dep[("births", 2025)], "deaths": dep[("deaths", 2025)], "consumption": dep[("consumption", 2025)], }) dd["offtake"] = dd["births"] - dd["deaths"] - dd["consumption"] - (dd["closing"] - dd["opening"]) dd["rate"] = dd["offtake"] / dd["opening"] dd = dd.reset_index() dd["name"] = dd["code"].map(names) dd = dd.sort_values("rate", ascending=False) cw.check("department offtakes sum to the national offtake", int(dd["offtake"].sum()), offtake, source="same books, two groupings") # Every department's books, re-derived from the CSVs. a24 = cw.source_csv(2024, "datosanimales.csv") a25 = cw.source_csv(2025, "datosanimales.csv") b24 = a24[a24["EspecieCodigo"].isin(["1", "11"])] b25 = a25[a25["EspecieCodigo"].isin(["1", "11"])] g = lambda d, col: cw.num(d[col]).groupby(d["DepartamentoCodigo"]).sum() src_off = (g(b25, "AnimalesPorEspecieNacimientosPD_AD") - g(b25, "AnimalesPorEspecieMortandadPD_AD") - g(b25, "AnimalesPorEspecieConsumoPD_AD") - (g(b25, "AnimalesPorEspeciePD_AD") - g(b24, "AnimalesPorEspeciePD_AD"))) cw.check("department offtakes: cube = CSV (largest difference, head)", int((dd.set_index("code")["offtake"] - src_off.reindex(dd["code"]).values).abs().max()), 0, source="datosanimales.csv 2024 and 2025, cattle only") cc.show_table(dd[["name", "opening", "births", "offtake", "rate"]].query("name != 'Montevideo'"), floatfmt=".3f", name="department-ledger") ``` ```text PASS department offtakes sum to the national offtake: 2,300,543 vs 2,300,543 (exactly) — same books, two groupings ``` ```text PASS department offtakes: cube = CSV (largest difference, head): 0 vs 0 (exactly) — datosanimales.csv 2024 and 2025, cattle only ``` | name | opening | births | offtake | rate | |:---------------|-----------------:|---------:|----------:|-------:| | Treinta y Tres | 613051 | 143895 | 160917 | 0.262 | | Rocha | 688313 | 181180 | 174553 | 0.254 | | Cerro Largo | 957379 | 231065 | 216665 | 0.226 | | Paysandú | 809798 | 188421 | 179667 | 0.222 | | Maldonado | 230533 | 55728 | 47540 | 0.206 | | Lavalleja | 644438 | 149071 | 127726 | 0.198 | | Tacuarembó | 1.03458e+06 | 244087 | 199859 | 0.193 | | Río Negro | 555782 | 112883 | 106598 | 0.192 | | Artigas | 730165 | 168821 | 138861 | 0.19 | | Durazno | 900286 | 223829 | 157244 | 0.175 | | Salto | 849010 | 213043 | 146395 | 0.172 | | Flores | 393191 | 91966 | 67201 | 0.171 | | Colonia | 551213 | 95197 | 92680 | 0.168 | | Canelones | 355686 | 51287 | 58553 | 0.165 | | Rivera | 608407 | 142668 | 96461 | 0.159 | | Florida | 1.09523e+06 | 220853 | 169868 | 0.155 | | Soriano | 570050 | 91871 | 81530 | 0.143 | | San José | 548346 | 91865 | 78096 | 0.142 | ### A correction to our own July report The July 2026 expedition printed Rocha's extraction rate as 21.4%. Here it is 25.4%. The difference is the bug this notebook's introduction describes: the July figure subtracted *every* species' deaths and home slaughter (sheep included) from Rocha's cattle books. Done that way again, the arithmetic reproduces the July number exactly, which is how we know that is what happened. ```python all_deaths = cw.num(a25["AnimalesPorEspecieMortandadPD_AD"]).groupby(a25["DepartamentoCodigo"]).sum() all_cons = cw.num(a25["AnimalesPorEspecieConsumoPD_AD"]).groupby(a25["DepartamentoCodigo"]).sum() r = dd.set_index("code").loc["14"] contaminated = (r["births"] - all_deaths["14"] - all_cons["14"] - (r["closing"] - r["opening"])) / r["opening"] cw.check("Rocha, species-honest (this notebook)", round(r["rate"], 3), 0.254, tol=0.0005, source="the table above") cw.check("Rocha, with every species' deaths and home slaughter (the July bug)", round(contaminated, 3), 0.214, tol=0.0005, source="expedition 2026-07-05 printed 21.4%") cw.finding("correction", f"The July 2026 expedition's figure for Rocha (21.4%) carried the all-species bug; species-honest, Rocha's " f"cattle offtake is **{r['rate']:.1%}** of its opening herd.") ``` ```text PASS Rocha, species-honest (this notebook): 0.254 vs 0.254 (within ±0.0005) — the table above PASS Rocha, with every species' deaths and home slaughter (the July bug): 0.214 vs 0.214 (within ±0.0005) — expedition 2026-07-05 printed 21.4% ``` > **Finding.** The July 2026 expedition's figure for Rocha (21.4%) carried the all-species bug; species-honest, Rocha's cattle offtake is **25.4%** of its opening herd. ```python top = dd.query("name != 'Montevideo'").iloc[0] low = dd.query("name != 'Montevideo'").iloc[-1] cw.finding("departments", f"By department the books run from **{top['name']}**, which shipped out {top['rate']:.1%} of its opening herd, " f"to {low['name']}, {low['rate']:.1%}. Montevideo (a few thousand head) is left out of the extremes.") cc.show(cc.choropleth(dd, "rate", title="Inferred offtake as a share of opening stock, 2024 → 2025", subtitle="cattle that left each department's farms (to slaughter, export, or another department)", legend="offtake rate", fmt=".0%", domain=[0, 0.3]), "offtake-map", thumbnail=True, alt_text="Map of offtake rate by department; the breeding east ships the largest share of its herd.") print(cc.map_credit()) ``` > **Finding.** By department the books run from **Treinta y Tres**, which shipped out 26.2% of its opening herd, to San José, 14.2%. Montevideo (a few thousand head) is left out of the extremes. ![Map of offtake rate by department; the breeding east ships the largest share of its herd.](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/offtake-map.svg) Chart data and encoding: [charts/offtake-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/offtake-map.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:--------------------------------------------------------------------|:--------------|:--------------|:---------------|:-----------------------------------------------------------| | 2024 cattle stock: cube = CSV | 12,138,148.00 | 12,138,148.00 | exactly | datosanimales.csv 2024, AnimalesPorEspeciePD_AD | | 2024 cattle births: cube = CSV | 2,364,279.00 | 2,364,279.00 | exactly | datosanimales.csv 2024, AnimalesPorEspecieNacimientosPD_AD | | 2024 cattle deaths: cube = CSV | 264,496.00 | 264,496.00 | exactly | datosanimales.csv 2024, AnimalesPorEspecieMortandadPD_AD | | 2024 cattle consumption: cube = CSV | 23,069.00 | 23,069.00 | exactly | datosanimales.csv 2024, AnimalesPorEspecieConsumoPD_AD | | 2025 cattle stock: cube = CSV | 12,265,269.00 | 12,265,269.00 | exactly | datosanimales.csv 2025, AnimalesPorEspeciePD_AD | | 2025 cattle births: cube = CSV | 2,697,988.00 | 2,697,988.00 | exactly | datosanimales.csv 2025, AnimalesPorEspecieNacimientosPD_AD | | 2025 cattle deaths: cube = CSV | 247,498.00 | 247,498.00 | exactly | datosanimales.csv 2025, AnimalesPorEspecieMortandadPD_AD | | 2025 cattle consumption: cube = CSV | 22,826.00 | 22,826.00 | exactly | datosanimales.csv 2025, AnimalesPorEspecieConsumoPD_AD | | offtake 2024 → 2025, head | 2,300,543.00 | 2,300,543.00 | exactly | cow-tools WP-0 oracle (e), 2026-07-06 | | extraction rate | 0.19 | 0.19 | within ±5e-05 | cow-tools WP-0 oracle (e): 18.95% | | department offtakes sum to the national offtake | 2,300,543.00 | 2,300,543.00 | exactly | same books, two groupings | | department offtakes: cube = CSV (largest difference, head) | 0.00 | 0.00 | exactly | datosanimales.csv 2024 and 2025, cattle only | | Rocha, species-honest (this notebook) | 0.25 | 0.25 | within ±0.0005 | the table above | | Rocha, with every species' deaths and home slaughter (the July bug) | 0.21 | 0.21 | within ±0.0005 | expedition 2026-07-05 printed 21.4% | ```text kind target rows first line 0 sparql uruguay-cows 38 SELECT ?year ?department ``` ```python cw.save() ``` --- ### Finding other Uruguay data Finding: Against the 2011 census (the latest by department in the catalogue's file), Uruguay has 3.73 cattle per person. In Durazno it is 16.7; in Montevideo, 0.0021. The dataset was found by meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes. Page: https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/finding-other-data/finding-other-data.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.md # Finding other Uruguay data **Answer.** Against the 2011 census (the latest by department in the catalogue's file), Uruguay has **3.73 cattle per person**. In **Durazno** it is 16.7; in Montevideo, 0.0021. The dataset was found by meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes. Notebook: https://cow-tools.sophia-labs.com/notebooks/finding-other-data/finding-other-data.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). ## The notebook cow-tools started with cows, but the point is the catalogue. Uruguay publishes its open data on `catalogodatos.gub.uy`, a CKAN site. The demo harvests that catalogue into the graph `uruguay-catalogue` as DCAT: every dataset, its publisher, its files and their download links. An agent can find a dataset **by meaning** (semantic search) and then read exactly where to fetch it (SPARQL over DCAT). The question for this notebook: *how many cattle are there per person, in each department?* We have the cattle. We need people, by department, and we will let the catalogue find them. ```python # Setup. import hashlib import io import unicodedata import urllib.request import altair as alt import pandas as pd import cowtools_client as cw import cowtools_charts as cc size = cw.sparql(""" SELECT (COUNT(DISTINCT ?d) AS ?datasets) (COUNT(DISTINCT ?p) AS ?publishers) WHERE { GRAPH ?g { ?d a dcat:Dataset . OPTIONAL { ?d dct:publisher ?p } } } """, graph=cw.CATALOGUE) print(f"catalogue graph {cw.CATALOGUE}: {size.iat[0, 0]:,} datasets from {size.iat[0, 1]:,} publishers") ``` ```text catalogue graph uruguay-catalogue: 2,718 datasets from 70 publishers ``` ## 1. Ask the catalogue, by meaning A plain English question. `semantic_search` ranks the catalogue's *cards* (one paragraph per dataset, grouped by publisher, each Spanish title with an English gloss) by meaning, not by keyword; each paragraph ends with the dataset's IRI in the DCAT graph, so a hit leads straight to the record. ```python import re hits = cw.tool("semantic_search", graphId=cw.CATALOGUE, query="how many people live in each department, from the population censuses", limit=10) rows = (hits.get("hits") or hits.get("results") or []) if isinstance(hits, dict) else hits def strings(v): if isinstance(v, str): yield v elif isinstance(v, dict): for x in v.values(): yield from strings(x) elif isinstance(v, list): for x in v: yield from strings(x) IRI = re.compile(r"https://catalogodatos\.gub\.uy/dataset/[0-9a-f-]{36}") ranked = [] for r in rows: for iri in IRI.findall(" ".join(strings(r))): if iri not in ranked: ranked.append(iri) print(f"{len(rows)} hits, {len(ranked)} distinct datasets named in them") ``` ```text 10 hits, 10 distinct datasets named in them ``` ## 2. Read the datasets' metadata (DCAT) For the datasets the search surfaced, the DCAT record says what they are, who published them, under what licence, and where their files are. ```python # The query: title, publisher and CSV files of the datasets the search named. (VALUES goes inside the # GRAPH block: outside it, the planner tries every dataset in every graph first and runs out of time.) values = " ".join(f"<{i}>" for i in ranked[:10]) dcat = cw.sparql(f""" SELECT ?dataset ?name ?title ?publisher ?license ?url WHERE {{ GRAPH ?g {{ VALUES ?dataset {{ {values} }} ?dataset a dcat:Dataset ; dct:title ?title . OPTIONAL {{ ?dataset ?name }} OPTIONAL {{ ?dataset dct:publisher ?p . ?p ?publisher }} OPTIONAL {{ ?dataset dct:license ?license }} OPTIONAL {{ ?dataset dcat:distribution ?dist . ?dist dcat:downloadURL ?url }} }} }} """, graph=cw.CATALOGUE) dcat["rank"] = dcat["dataset"].map(ranked.index) dcat = dcat.sort_values("rank") cc.show_table(dcat.drop_duplicates("dataset")[["rank", "title", "publisher"]], name="search-hits") ``` | rank | title | publisher | |-------:|:-------------------------------------------------------------------------------------------------------------------|:------------| | 0 | Cantidad de personas según departamento por sexo. Censos 1963-2011 | MIDES | | 1 | Cantidad de personas que residen en asentamientos irregulares según departamento. Total país | MIDES | | 2 | Cantidad de personas según departamento. Censos 1963 a 2011 | MIDES | | 3 | Cantidad de personas según departamento por tramos de edad. Censo 2011 | MIDES | | 4 | Cantidad de personas según tramos de edad por departamento. Total país | MIDES | | 5 | Cantidad de personas según sexo y departamento por tramos de edad . Censo 2011 | MIDES | | 6 | Cantidad de personas mayores según departamento. Total país | MIDES | | 7 | Cantidad de personas mayores según sexo por departamento. Total país | MIDES | | 8 | Distribución porcentual de personas según departamento por tramos de edad. Censo 2011 | MIDES | | 9 | Distribución porcentual de personas según departamento de residencia habitual por lugar de nacimiento. Censos 2011 | MIDES | ```python csvs = dcat[dcat["url"].fillna("").str.lower().str.endswith(".csv")] # Several hits are the same census cut finer (by sex, by age). We want the plain count of people per # department, the one titled exactly so. pick = csvs[csvs["title"].str.match(r"Cantidad de personas según departamento\. Censos")] cw.check("semantic search finds the people-by-department census dataset, with a CSV, in its top ten", len(pick) >= 1, True, source="semantic_search over uruguay-catalogue, then its DCAT records") chosen = pick.iloc[0] cw.check("…and ranks it in the top five", int(chosen["rank"]) < 5, True, source=f"rank {int(chosen['rank']) + 1}") print("dataset: ", chosen["title"], f"({chosen['name']})") print("publisher:", chosen["publisher"]) print("licence: ", chosen["license"]) print("file: ", chosen["url"]) ``` ```text PASS semantic search finds the people-by-department census dataset, with a CSV, in its top ten: True vs True (exactly) — semantic_search over uruguay-catalogue, then its DCAT records PASS …and ranks it in the top five: True vs True (exactly) — rank 3 dataset: Cantidad de personas según departamento. Censos 1963 a 2011 (mides-indicador-10461) publisher: MIDES licence: https://www.gub.uy/agencia-gobierno-electronico-sociedad-informacion-conocimiento/sites/agencia-gobierno-electronico-sociedad-informacion-conocimiento/files/documentos/publicaciones/licencia_de_datos_abiertos_0.pdf file: https://catalogodatos.gub.uy/dataset/d26193c8-0639-40bf-8482-f05cb483cd31/resource/1a8e5fe2-c2e4-477f-ac07-e5ca38667448/download/10461_cantidad_de_personas_segun_departamento-_censos_1963_a_2011.csv ``` ## 3. Fetch it, and keep its fingerprint The file comes from the URL the catalogue recorded, nothing else. We print its SHA-256 so anyone can tell whether they are looking at the same bytes. ```python with urllib.request.urlopen(chosen["url"], timeout=120) as r: raw = r.read() sha = hashlib.sha256(raw).hexdigest() people = pd.read_csv(io.BytesIO(raw), encoding="latin-1") people.columns = ["departamento", "year", "people"] print(f"{len(raw):,} bytes, sha256 {sha}") people.tail(3) ``` ```text 2,700 bytes, sha256 7c184f2d790ed4b9d9e65d861870527e3fcc638de37ebf34ad37f6840637073e ``` ```text departamento year people 111 Soriano 2011 82594 112 Tacuarembó 2011 90051 113 Treinta y Tres 2011 48134 ``` ## 4. Join on the department spine The census file names departments in plain Spanish ("Paysandu", "San José"); DICOSE codes them 1–19. Folding accents and case joins the two, and the join must match all 19 or the notebook stops. ```python def fold(s: str) -> str: return "".join(c for c in unicodedata.normalize("NFKD", str(s)) if not unicodedata.combining(c)).upper().strip() census = people[people["year"] == 2011].assign(key=lambda d: d["departamento"].map(fold)) depts = cw.departments().assign(key=lambda d: d["label"].map(fold)) joined = depts.merge(census, on="key", how="left") cw.check("2011 census rows join all 19 departments", int(joined["people"].notna().sum()), 19, source="DICOSE codelist ⨝ census file, by folded name") ``` ```text PASS 2011 census rows join all 19 departments: 19 vs 19 (exactly) — DICOSE codelist ⨝ census file, by folded name ``` ### Cross-check: a second dataset from the same search The search's other hits include the same census cut by sex (`mides-indicador-10769`). Its men and women, added up, must give the same people in every department in 2011. ```python by_sex_row = dcat[(dcat["name"] == "mides-indicador-10769") & dcat["url"].fillna("").str.endswith(".csv")] cw.check("the by-sex census table is among the search hits, with a CSV", len(by_sex_row) >= 1, True, source="semantic_search + DCAT") with urllib.request.urlopen(by_sex_row.iloc[0]["url"], timeout=120) as r: sex_raw = r.read() sex = pd.read_csv(io.BytesIO(sex_raw), encoding="latin-1") sex.columns = ["sex", "departamento", "year", "people"] sex11 = sex[sex["year"] == 2011].assign(key=lambda d: d["departamento"].map(fold)).groupby("key")["people"].sum() mismatch = int((census.set_index("key")["people"] - sex11.reindex(census["key"]).values).abs().sum()) cw.check("2011 people per department: by-department table = by-sex table (total difference)", mismatch, 0, source=f"mides-indicador-10461 vs mides-indicador-10769, sha256 {hashlib.sha256(sex_raw).hexdigest()[:12]}…") total_2011 = int(census["people"].sum()) INE_2011 = 3_286_314 # INE's published total for the 2011 census print(f"The department tables sum to {total_2011:,} people in 2011; INE's published national total is {INE_2011:,}, " f"{INE_2011 - total_2011:,} more. We use the department tables, which is what a join on departments needs, " "and do not know where the difference sits.") ``` ```text PASS the by-sex census table is among the search hits, with a CSV: True vs True (exactly) — semantic_search + DCAT ``` ```text PASS 2011 people per department: by-department table = by-sex table (total difference): 0 vs 0 (exactly) — mides-indicador-10461 vs mides-indicador-10769, sha256 d096b027440f… The department tables sum to 3,285,877 people in 2011; INE's published national total is 3,286,314, 437 more. We use the department tables, which is what a join on departments needs, and do not know where the difference sits. ``` ```python cattle = cw.sparql(""" SELECT ?department (SUM(?n) AS ?cattle) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year "2025"^^xsd:gYear ; cow:department ?department ; cow:species ?s ; cow:animalsCount ?n . VALUES ?s { } } } GROUP BY ?department """) cattle["code"] = cattle["department"].map(cw.dept_code) t = joined.merge(cattle[["code", "cattle"]], on="code") t["cattle_per_person"] = t["cattle"] / t["people"] t = t.sort_values("cattle_per_person", ascending=False) national = t["cattle"].sum() / t["people"].sum() cw.check("2025 cattle total after the join", int(t["cattle"].sum()), 12_265_269, source="notebook national-herd") cc.show_table(t[["name", "cattle", "people", "cattle_per_person"]], floatfmt=",.2f", name="cattle-per-person") ``` ```text PASS 2025 cattle total after the join: 12,265,269 vs 12,265,269 (exactly) — notebook national-herd ``` | name | cattle | people | cattle_per_person | |:---------------|:----------|:----------|--------------------:| | Durazno | 952,171 | 57,084 | 16.68 | | Florida | 1,117,097 | 67,047 | 16.66 | | Flores | 409,429 | 25,050 | 16.34 | | Treinta y Tres | 584,734 | 48,134 | 12.15 | | Tacuarembó | 1,061,136 | 90,051 | 11.78 | | Cerro Largo | 950,412 | 84,698 | 11.22 | | Lavalleja | 654,451 | 58,815 | 11.13 | | Artigas | 742,198 | 73,377 | 10.11 | | Río Negro | 549,369 | 54,765 | 10.03 | | Rocha | 682,644 | 68,088 | 10.03 | | Salto | 898,899 | 124,861 | 7.2 | | Paysandú | 801,512 | 113,107 | 7.09 | | Soriano | 567,452 | 82,594 | 6.87 | | Rivera | 639,917 | 103,473 | 6.18 | | San José | 541,254 | 108,304 | 5 | | Colonia | 537,066 | 123,203 | 4.36 | | Maldonado | 234,191 | 164,298 | 1.43 | | Canelones | 338,601 | 520,173 | 0.65 | | Montevideo | 2,736 | 1,318,755 | 0 | ```python cw.finding("headline", f"Against the 2011 census (the latest by department in the catalogue's file), Uruguay has " f"**{national:.2f} cattle per person**. In **{t.iloc[0]['name']}** it is {t.iloc[0]['cattle_per_person']:.1f}; " f"in Montevideo, {t.set_index('name').loc['Montevideo', 'cattle_per_person']:.4f}. The dataset was found by " f"meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes.") ``` > **Finding.** Against the 2011 census (the latest by department in the catalogue's file), Uruguay has **3.73 cattle per person**. In **Durazno** it is 16.7; in Montevideo, 0.0021. The dataset was found by meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes. ```python cc.show(cc.choropleth(t, "cattle_per_person", title="Cattle per person, by department", subtitle="cattle 30 June 2025 (DICOSE) ÷ people at the 2011 census (INE, via the catalogue)", legend="cattle per person", fmt=".1f"), "cattle-per-person-map", thumbnail=True, alt_text="Map: cattle per person is highest in Durazno, Florida and Flores (about 16), near zero in Montevideo.") print(cc.map_credit()) ``` ![Map: cattle per person is highest in Durazno, Florida and Flores (about 16), near zero in Montevideo.](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/charts/cattle-per-person-map.svg) Chart data and encoding: [charts/cattle-per-person-map.vl.json](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/charts/cattle-per-person-map.vl.json) (Vega-Lite). ```text Map: Natural Earth 1:10m admin-1 (public domain, v5.1.2), joined on the DICOSE department code. Made with Natural Earth. ``` **A caveat, stated rather than hidden.** The herd is from 2025, the people from 2011: Uruguay's 2023 census counted more people (about 3.44 million), so these ratios run a little high. The catalogue file is the one by department that the catalogue holds; when a newer one is harvested, this notebook's search will find it. ## Where every number came from ```python cc.show_table(cw.checks()[["check", "got", "expected", "rule", "source"]], name="checks") cw.provenance() ``` | check | got | expected | rule | source | |:------------------------------------------------------------------------------------------|---------:|-----------:|:--------|:---------------------------------------------------------------------| | semantic search finds the people-by-department census dataset, with a CSV, in its top ten | True | True | exactly | semantic_search over uruguay-catalogue, then its DCAT records | | …and ranks it in the top five | True | True | exactly | rank 3 | | 2011 census rows join all 19 departments | 19 | 19 | exactly | DICOSE codelist ⨝ census file, by folded name | | the by-sex census table is among the search hits, with a CSV | True | True | exactly | semantic_search + DCAT | | 2011 people per department: by-department table = by-sex table (total difference) | 0 | 0 | exactly | mides-indicador-10461 vs mides-indicador-10769, sha256 d096b027440f… | | 2025 cattle total after the join | 12265269 | 12265269 | exactly | notebook national-herd | ```text kind target rows \ 0 sparql uruguay-catalogue 1.0 1 sparql uruguay-catalogue 40.0 2 sparql uruguay-cows 19.0 3 tool semantic_search NaN first line 0 SELECT (COUNT(DISTINCT ?d) AS ?datasets) (COUN... 1 SELECT ?dataset ?name ?title ?publisher ?licen... 2 SELECT ?department (SUM(?n) AS ?cattle) 3 {"graphId": "uruguay-catalogue", "query": "how... ``` ```python cw.save() ``` --- ### Ask the agent Finding: Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. Page: https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html · Notebook: https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/ask-the-agent.ipynb · Markdown: https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.md # Ask the agent Notebook: https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/ask-the-agent.ipynb · Page: https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html · Data: Uruguay MGAP/SNIG DICOSE 2024–2025 (graph `uruguay-cows` at https://cow-tools.sophia-labs.com/mcp). > Shipped unexecuted: it talks to a model, so it runs on your own OpenRouter key (BYOK, the X-Model-Key header). Set OPENROUTER_API_KEY and run it; the site's build spends no model money. ## The notebook The demo hosts personal agents over its graphs. You open a session, talk to it, leave, and come back to the same conversation later. The protocol is Vehicle's **ride protocol** (`sophia.vehicle-ride.v2`): plain HTTP plus a long-poll (or SSE) event stream, the same one the chat box on the site uses. Reading the data and the tools is free. A conversation costs model money, so it needs one of two things: **your own OpenRouter key**, sent with every request in the `X-Model-Key` header (held in memory for the session, never stored), or a Sophia account with credit. This notebook uses your key. And because this is cow-tools, we do not take the agent's word for it: the last cell checks its answer against the cube. ```python # Setup: your OpenRouter key from the environment (never paste it into a notebook). import json import os import time import urllib.request import uuid import cowtools_client as cw KEY = os.environ.get("OPENROUTER_API_KEY") if not KEY: raise SystemExit("set OPENROUTER_API_KEY to run this notebook (https://openrouter.ai/keys)") RIDE = f"{cw.BASE_URL}/services/vehicle/g/{cw.COWS}" CLIENT = f"notebook-{uuid.uuid4().hex[:8]}" def ride(method: str, path: str, body: dict | None = None) -> dict: headers = {"Content-Type": "application/json", "X-Model-Key": KEY, "X-Vehicle-Client-Id": CLIENT} if cw.TOKEN: headers["Authorization"] = f"Bearer {cw.TOKEN}" req = urllib.request.Request(RIDE + path, method=method, headers=headers, data=json.dumps(body).encode() if body is not None else None) with urllib.request.urlopen(req, timeout=60) as r: frame = json.loads(r.read()) if frame.get("type") == "error": raise cw.CowToolsError(f"{frame.get('code')}: {frame.get('message')}") return frame ``` ## Open a session A session is bound to the graph in its path (`/g/uruguay-cows/`). The `requestId` makes each call idempotent: send it twice, it happens once. ```python created = ride("POST", "/sessions", {"requestId": f"req-{uuid.uuid4()}", "title": "cow-tools notebook", "model": "openrouter/openai/gpt-6-luna"}) session = created["value"]["session"]["sessionId"] print("session:", session) ``` ## Ask, then watch the events `prompt` starts a run. `watch` long-polls the event log from a cursor until the run settles; every event carries a sequence number, so a client that drops off can resume where it left. ```python question = ("How many dairy cows (milking plus dry) did Florida declare on 30 June 2025, by the PD_PF count? " "Answer with the number first, then the query you used.") ride("POST", f"/sessions/{session}/commands", {"requestId": f"req-{uuid.uuid4()}", "op": "prompt", "text": question}) since, replies, cost, done = 0, [], 0.0, False deadline = time.time() + 180 while not done and time.time() < deadline: frame = ride("GET", f"/sessions/{session}/events?since={since}&waitMs=25000") for ev in frame["value"]["events"]: since = max(since, ev["seq"]) p = ev["payload"] if ev["type"] == "tool.started": print("tool:", p.get("toolName") or p.get("name")) if ev["type"] == "message.completed" and p.get("role") == "assistant": replies.append(p.get("text", "")) cost += p.get("usage", {}).get("costUsd", 0) if ev["type"] in ("run.settled", "run.error"): done = True answer = replies[-1] if replies else "" print(answer) print(f"model cost: ${cost:.4f}") ``` ## Come back later The session outlives this notebook. `inspect` returns its summary and transcript; `capsule` a compact record. Note the session id and you can pick the conversation up from any client. ```python snapshot = ride("GET", f"/sessions/{session}") print(json.dumps(snapshot["value"].get("summary", snapshot["value"]), indent=1)[:800]) ``` ## Check the agent ```python truth = cw.sparql_value(""" SELECT (SUM(?pf) AS ?cows) WHERE { GRAPH ?g { ?obs a cow:AnimalCategoryStockObservation ; cow:year "2025"^^xsd:gYear ; cow:department ; cow:species ; cow:animalCategory ?c ; cow:animalsCountPf ?pf . VALUES ?c { } } } """) said = [int(x.replace(",", "")) for x in __import__("re").findall(r"\b\d{1,3}(?:,\d{3})+\b|\b\d{4,}\b", answer)] cw.check("the agent's first number is the cube's", said[0] if said else None, int(truth), source="SPARQL over uruguay-cows, categories 11/2 and 11/3, PD_PF") cw.finding("headline", f"The agent answered {said[0] if said else 'nothing'}; the cube says {int(truth):,}.") cw.save() ``` ## The guide A document for each of the nineteen departments, a glossary of what DICOSE means by a vaquillona, a reading path for the newly curious, and a companion note for every notebook. Pages to read here, each with a markdown twin for your agent. Pages: https://cow-tools.sophia-labs.com/guide/; every document below is also at its own address (the markdown twin named after each heading). ### Reading path **Start with the national herd, end with an agent: nine notebooks, nineteen departments, one glossary.** cow-tools is Sophia's proof of concept: everything Uruguay publishes about its livestock, as a graph agents and people can question, with the provenance of every number. *Why would anyone want to know so much about… Uruguay?* #### The notebooks, in order 1. [**The national herd at a glance**](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md): Uruguay's holders declared 12,265,269 cattle on 30 June 2025 (11,583,321 beef and 681,948 dairy) and 4,799,066 sheep. On 2024, cattle changed +1.05% and sheep -11.47%. 2. [**Cattle and sheep, department by department**](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md): Only Salto and Artigas still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell 11.5% in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep. 3. [**Dairy country**](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md): Florida, San José, Colonia produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%. 4. [**Breeders in the east, finishers in the west**](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md): Maldonado is the most breeding-heavy department: 71.7% of its beef herd is breeding cows and calves. Soriano leans hardest to finishing: 29.8% steers and fattening cows. The east breeds; the west finishes. 5. [**How hard the land is stocked**](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md): Uruguay carries 0.856 cattle per hectare of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, San José, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65. 6. [**One year on, 2024 to 2025**](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md): Between the 2024 and 2025 declarations Uruguay gained 127,121 cattle (+1.05%) and lost 621,595 sheep (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands. 7. [**The herd ledger**](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md): Uruguay's cattle books balance only if 2,300,543 head left the farms between the 2024 and 2025 declarations: 18.95% of the opening herd. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121). 8. [**Finding other Uruguay data**](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md): Against the 2011 census (the latest by department in the catalogue's file), Uruguay has 3.73 cattle per person. In Durazno it is 16.7; in Montevideo, 0.0021. The dataset was found by meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes. 9. **Ask the agent** *(unexecuted)* ([`notebook-ask-the-agent`](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### The departments | department | cattle 2025 | sheep 2025 | milk share | document | | --- | --- | --- | --- | --- | | Florida | 1,117,097 | 202,434 | 26.5% | [`department-florida`](https://cow-tools.sophia-labs.com/guide/department-florida/index.md) | | Tacuarembó | 1,061,136 | 398,742 | 0.2% | [`department-tacuarembo`](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md) | | Durazno | 952,171 | 290,920 | 9.2% | [`department-durazno`](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md) | | Cerro Largo | 950,412 | 303,495 | 0.2% | [`department-cerro-largo`](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md) | | Salto | 898,899 | 1,032,181 | 0.9% | [`department-salto`](https://cow-tools.sophia-labs.com/guide/department-salto/index.md) | | Paysandú | 801,512 | 555,079 | 2.3% | [`department-paysandu`](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md) | | Artigas | 742,198 | 801,403 | 0.0% | [`department-artigas`](https://cow-tools.sophia-labs.com/guide/department-artigas/index.md) | | Rocha | 682,644 | 154,813 | 0.5% | [`department-rocha`](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md) | | Lavalleja | 654,451 | 261,086 | 0.6% | [`department-lavalleja`](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md) | | Rivera | 639,917 | 182,585 | 0.2% | [`department-rivera`](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md) | | Treinta y Tres | 584,734 | 178,572 | 0.2% | [`department-treinta-y-tres`](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) | | Soriano | 567,452 | 55,293 | 5.8% | [`department-soriano`](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md) | | Río Negro | 549,369 | 69,144 | 3.6% | [`department-rio-negro`](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md) | | San José | 541,254 | 37,781 | 22.6% | [`department-san-jose`](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md) | | Colonia | 537,066 | 38,341 | 19.2% | [`department-colonia`](https://cow-tools.sophia-labs.com/guide/department-colonia/index.md) | | Flores | 409,429 | 83,001 | 2.5% | [`department-flores`](https://cow-tools.sophia-labs.com/guide/department-flores/index.md) | | Canelones | 338,601 | 50,487 | 4.9% | [`department-canelones`](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md) | | Maldonado | 234,191 | 101,340 | 0.6% | [`department-maldonado`](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md) | | Montevideo | 2,736 | 2,369 | 0.0% | [`department-montevideo`](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md) | #### The guide - [*Finding other Uruguay data*](https://cow-tools.sophia-labs.com/guide/finding-other-uruguay-data/index.md) - [*How to read the cubes*](https://cow-tools.sophia-labs.com/guide/reading-the-cubes/index.md) - [*Known caveats*](https://cow-tools.sophia-labs.com/guide/caveats/index.md) - [*Questions with exact answers*](https://cow-tools.sophia-labs.com/guide/questions-with-exact-answers/index.md) - [*What DICOSE is*](https://cow-tools.sophia-labs.com/guide/what-is-dicose/index.md) #### Reference - [`glossary-dicose`](https://cow-tools.sophia-labs.com/guide/glossary-dicose/index.md): DICOSE, census areas, PD_AD and PD_PF, the categories, the cube. - [`how-to-ask-this-data`](https://cow-tools.sophia-labs.com/guide/how-to-ask-this-data/index.md): MCP, SPARQL and Python, with examples run at build time. Everything here is also on the web: https://cow-tools.sophia-labs.com/ (the notebooks are listed on the front page). #### Connected (the graph's wires) - Next in the reading path: [The national herd at a glance](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Start here: https://cow-tools.sophia-labs.com/guide/reading-path/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `reading-path` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/reading-path/index.md · page: https://cow-tools.sophia-labs.com/guide/reading-path/) --- ### The national herd at a glance **Uruguay's holders declared 12,265,269 cattle on 30 June 2025 (11,583,321 beef and 681,948 dairy) and 4,799,066 sheep. On 2024, cattle changed +1.05% and sheep -11.47%.** #### Findings - **Florida** has the most cattle (1,117,097); Montevideo the fewest (2,736). The five largest departments hold 40.6% of the national herd. #### Charts ![Horizontal bars: beef cattle 11.6 million, sheep 4.8 million, dairy cattle 0.68 million, horses, pigs and goats far smaller.](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/species-2025.png) *species-2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/species-2025.vl.json) ![Map of Uruguay's 19 departments shaded by cattle; the darkest are in the centre and north (Florida, Tacuarembó, Durazno, Cerro Largo), the lightest is Montevideo.](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/cattle-map-2025.png) *Cattle by department, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/national-herd/charts/cattle-map-2025.vl.json) #### How we know The notebook ran **20 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | 2024 bovinos: cube = CSV | 11,449,817 | 11,449,817 | exactly | | 2024 bovinos de leche: cube = CSV | 688,331 | 688,331 | exactly | | 2024 ovinos: cube = CSV | 5,420,661 | 5,420,661 | exactly | | 2024 yeguarizos: cube = CSV | 398,724 | 398,724 | exactly | | 2024 caprinos: cube = CSV | 9,772 | 9,772 | exactly | | 2024 suinos: cube = CSV | 110,583 | 110,583 | exactly | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) - Download: [national-herd.ipynb](https://cow-tools.sophia-labs.com/notebooks/national-herd/national-herd.ipynb) (also in this workspace: file [`ipynb-national-herd`](https://cow-tools.sophia-labs.com/notebooks/national-herd/national-herd.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.md) Reading path: next: [*Cattle and sheep, department by department*](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "The national herd at a glance", "abstract": "Uruguay's holders declared 12,265,269 cattle on 30 June 2025 (11,583,321 beef and 681,948 dairy) and 4,799,066 sheep. On 2024, cattle changed +1.05% and sheep -11.47%.", "url": "https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/national-herd/national-herd.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [Reading path](https://cow-tools.sophia-labs.com/guide/reading-path/index.md) - Next in the reading path: [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md) - Related: [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-national-herd/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-national-herd` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-national-herd/) --- ### Cattle and sheep, department by department **Only Salto and Artigas still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell 11.5% in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep.** #### Findings - Every one of the 19 departments declared fewer sheep in 2025. The steepest fall was in **Río Negro** (-18.3%); in absolute heads, Salto lost the most (118,943). #### Charts ![Map: sheep are over half the heads in Salto and Artigas; Montevideo (46%, a few thousand animals) and Paysandú (41%) follow; lowest in San José and Colonia.](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-share-map-2025.png) *Sheep as a share of cattle + sheep, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-share-map-2025.vl.json) ![Diverging map: every department is brown, a fall in sheep everywhere; the steepest is Río Negro.](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-change-map.png) *Change in sheep, 2024 → 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/sheep-change-map.vl.json) ![Nineteen small panels, one per department, each with cattle and sheep bars for 2024 and 2025; sheep bars shrink everywhere.](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/small-multiples.png) *Cattle and sheep by department, 2024 and 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/charts/small-multiples.vl.json) #### How we know The notebook ran **6 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | 2025 cattle and sheep, all 19 departments: cube = CSV (mismatching cells) | 0 | 0 | exactly | | Salto sheep share of heads | 0.535 | 0.535 | within ±0.0005 | | Artigas sheep share of heads | 0.519 | 0.519 | within ±0.0005 | | San José sheep share of heads | 0.065 | 0.065 | within ±0.0005 | | national sheep 2024 → 2025 | -0.1147 | -0.1147 | within ±5e-05 | | every department lost sheep | True | True | exactly | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) - Download: [cattle-and-sheep.ipynb](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/cattle-and-sheep.ipynb) (also in this workspace: file [`ipynb-cattle-and-sheep`](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/cattle-and-sheep.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.md) Reading path: previous: [*The national herd at a glance*](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md); next: [*Dairy country*](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "Cattle and sheep, department by department", "abstract": "Only Salto and Artigas still have more sheep than cattle by heads (53.5% and 51.9% sheep). The national flock fell 11.5% in one year, from 5,420,661 to 4,799,066: 621,595 fewer sheep.", "url": "https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/cattle-and-sheep.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [The national herd at a glance](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md) - Next in the reading path: [Dairy country](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md) - Related: [Artigas](https://cow-tools.sophia-labs.com/guide/department-artigas/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-cattle-and-sheep` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/) --- ### Dairy country **Florida, San José, Colonia produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%.** #### Findings - Of the 2,298,402,318 litres declared in 2025, **318,070 were goat's milk**, 60% of it from San José. - Florida had **100,116 dairy cows** on 30 June 2025 by DICOSE's dairy convention (own animals, PD_PF), or 103,472 counting the animals on its holdings (PD_AD); 182,610 dairy cattle of all ages. - **San José** produces 1,605 litres per hectare of livestock land, 2.5× Florida's 645: Florida has the volume, San José the intensity. #### Charts ![Map: milk is concentrated in Florida, San José and Colonia in the south-west; the north and east produce almost none.](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/milk-share-map.png) *Share of Uruguay's milk, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/milk-share-map.vl.json) ![Bars: San José leads at about 1,600 litres per livestock hectare, then Colonia (about 1,280) and Florida (about 650).](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/litres-per-ha.png) *litres-per-ha.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/dairy-country/charts/litres-per-ha.vl.json) #### How we know The notebook ran **14 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | 2024 litres per department: cube = CSV (largest difference, litres) | 0 | 0 | exactly | | 2024 national litres: cube = CSV | 2,260,567,177 | 2,260,567,177 | exactly | | 2025 litres per department: cube = CSV (largest difference, litres) | 0 | 0 | exactly | | 2025 national litres: cube = CSV | 2,298,402,318 | 2,298,402,318 | exactly | | Florida share of milk | 0.265 | 0.265 | within ±0.0005 | | San José share of milk | 0.226 | 0.226 | within ±0.0005 | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) - Download: [dairy-country.ipynb](https://cow-tools.sophia-labs.com/notebooks/dairy-country/dairy-country.ipynb) (also in this workspace: file [`ipynb-dairy-country`](https://cow-tools.sophia-labs.com/notebooks/dairy-country/dairy-country.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.md) Reading path: previous: [*Cattle and sheep, department by department*](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md); next: [*Breeders in the east, finishers in the west*](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "Dairy country", "abstract": "Florida, San José, Colonia produce 68.3% of Uruguay's milk (2,298.4 million litres in 2025, +1.67% on 2024). Florida makes the most: 26.5%.", "url": "https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/dairy-country/dairy-country.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md) - Next in the reading path: [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md) - Related: [Colonia](https://cow-tools.sophia-labs.com/guide/department-colonia/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-dairy-country` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/) --- ### Breeders in the east, finishers in the west **Maldonado is the most breeding-heavy department: 71.7% of its beef herd is breeding cows and calves. Soriano leans hardest to finishing: 29.8% steers and fattening cows. The east breeds; the west finishes.** #### Charts ![Stacked bars per department: eastern departments (Maldonado, Treinta y Tres, Rocha) have the largest breeding share; Soriano and Río Negro the largest share of steers.](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/composition.png) *Beef herd composition by department, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/composition.vl.json) ![Map: the finishing ratio is highest in the littoral west (Soriano, Río Negro) and lowest in Maldonado.](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/finishing-map.png) *Steers and fattening cows per breeding animal, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/herd-structure/charts/finishing-map.vl.json) #### How we know The notebook ran **7 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | every beef category maps to a group | 0 | 0 | exactly | | 2025 beef cattle by department × category: cube = CSV (largest difference) | 0 | 0 | exactly | | 2025 beef categories sum to the beef total in datosanimales | 11,583,321 | 11,583,321 | exactly | | derived rows cover every department × category | 304 | 304 | exactly | | category_share_of_bovine (derived, 6 dp) = our shares on its denominator (largest gap) | 5e-07 | 0 | within ±5e-07 | | the most breeding-heavy department is in the east | True | True | exactly | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) - Download: [herd-structure.ipynb](https://cow-tools.sophia-labs.com/notebooks/herd-structure/herd-structure.ipynb) (also in this workspace: file [`ipynb-herd-structure`](https://cow-tools.sophia-labs.com/notebooks/herd-structure/herd-structure.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.md) Reading path: previous: [*Dairy country*](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md); next: [*How hard the land is stocked*](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "Breeders in the east, finishers in the west", "abstract": "Maldonado is the most breeding-heavy department: 71.7% of its beef herd is breeding cows and calves. Soriano leans hardest to finishing: 29.8% steers and fattening cows. The east breeds; the west finishes.", "url": "https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/herd-structure/herd-structure.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [Dairy country](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md) - Next in the reading path: [How hard the land is stocked](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md) - Related: [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-herd-structure` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/) --- ### How hard the land is stocked **Uruguay carries 0.856 cattle per hectare of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, San José, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65.** #### Findings - Density follows the sown pasture: across departments, Spearman ρ = **0.847** between cattle per hectare and the share of land under *praderas*. Nationally 72.4% of declared land is native grassland and only 6.9% sown pasture: intensity is a thin southern veneer. - Of 629 census areas with at least 100 livestock hectares, the densest is area **317003 in Canelones** at 8.33 cattle per hectare; the median area carries 0.91. #### Charts ![Map: stocking density is highest in the south-west (San José, Colonia, Canelones) and lowest in the north-west (Artigas, Salto).](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-map.png) *Cattle per hectare of livestock land, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-map.vl.json) ![Scatter: departments with more sown pasture carry more cattle per hectare; San José and Colonia top right, Artigas and Salto bottom left.](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-vs-praderas.png) *density-vs-praderas.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/density-vs-praderas.vl.json) ![Strip plot: each department's census areas as ticks along a density axis; the south-west spreads furthest right.](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/areas-strip.png) *Cattle per livestock hectare, by census area, 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/charts/areas-strip.vl.json) #### How we know The notebook ran **11 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | livestock hectares per department: cube = CSV (largest difference, ha) | 0 | 0 | exactly | | cattle per department: cube = CSV (largest difference, heads) | 0 | 0 | exactly | | national livestock hectares, millions | 14.32 | 14.32 | within ±0.005 | | national density, cattle per livestock ha | 0.856 | 0.856 | within ±0.0005 | | San José density | 1.67 | 1.67 | within ±0.005 | | all 19 densities = the cube's derived metric (largest gap) | 0 | 0 | within ±1e-06 | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) - Download: [stocking-intensity.ipynb](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/stocking-intensity.ipynb) (also in this workspace: file [`ipynb-stocking-intensity`](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/stocking-intensity.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.md) Reading path: previous: [*Breeders in the east, finishers in the west*](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md); next: [*One year on, 2024 to 2025*](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "How hard the land is stocked", "abstract": "Uruguay carries 0.856 cattle per hectare of livestock land (12,265,269 cattle on 14.32 million ha). The densest department, San José, carries 1.67; the sparsest of the big grazing departments, Artigas, 0.65.", "url": "https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/stocking-intensity.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md) - Next in the reading path: [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md) - Related: [Artigas](https://cow-tools.sophia-labs.com/guide/department-artigas/index.md), [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-stocking-intensity` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/) --- ### One year on, 2024 to 2025 **Between the 2024 and 2025 declarations Uruguay gained 127,121 cattle (+1.05%) and lost 621,595 sheep (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands.** #### Findings - Growth came from the north and centre (**Salto** +5.9%, Durazno +5.8%, Rivera +5.2%); the south and east shrank (**Canelones** -4.8%, Treinta y Tres -4.6%). #### Charts ![Diverging map: the north and centre (Salto, Durazno, Rivera) gained the most cattle; Canelones and Treinta y Tres lost the most.](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-change-map.png) *Change in cattle, 2024 → 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-change-map.vl.json) ![Slope chart: most department lines rise gently; Canelones and Treinta y Tres fall.](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-slope.png) *Cattle by department, 2024 → 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/year-over-year/charts/cattle-slope.vl.json) #### How we know The notebook ran **15 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | both years passed their quality gate | True | True | exactly | | no blocking violations in either year | 0 | 0 | exactly | | every counted warning is recorded | 4 | 4 | exactly | | no warning touches the dimensions this comparison uses | [] | [] | exactly | | 2024 holders declaring beef cattle: cube = CSV | 61,561 | 61,561 | exactly | | 2025 holders declaring beef cattle: cube = CSV | 59,121 | 59,121 | exactly | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) - Download: [year-over-year.ipynb](https://cow-tools.sophia-labs.com/notebooks/year-over-year/year-over-year.ipynb) (also in this workspace: file [`ipynb-year-over-year`](https://cow-tools.sophia-labs.com/notebooks/year-over-year/year-over-year.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.md) Reading path: previous: [*How hard the land is stocked*](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md); next: [*The herd ledger*](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "One year on, 2024 to 2025", "abstract": "Between the 2024 and 2025 declarations Uruguay gained 127,121 cattle (+1.05%) and lost 621,595 sheep (-11.47%), while the number of holders declaring beef cattle went from 61,561 to 59,121 (-4.0%): more cattle, fewer hands.", "url": "https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/year-over-year/year-over-year.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [How hard the land is stocked](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md) - Next in the reading path: [The herd ledger](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md) - Related: [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-year-over-year` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/) --- ### The herd ledger **Uruguay's cattle books balance only if 2,300,543 head left the farms between the 2024 and 2025 declarations: 18.95% of the opening herd. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121).** #### Findings - The July 2026 expedition's figure for Rocha (21.4%) carried the all-species bug; species-honest, Rocha's cattle offtake is **25.4%** of its opening herd. - By department the books run from **Treinta y Tres**, which shipped out 26.2% of its opening herd, to San José, 14.2%. Montevideo (a few thousand head) is left out of the extremes. #### Charts ![Waterfall: 12.14 million opening stock, plus 2.70 million births, minus small deaths and home slaughter, minus 2.30 million offtake, gives 12.27 million closing stock.](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/ledger-waterfall.png) *Uruguay's cattle ledger, 30 June 2024 → 30 June 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/ledger-waterfall.vl.json) ![Map of offtake rate by department; the breeding east ships the largest share of its herd.](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/offtake-map.png) *Inferred offtake as a share of opening stock, 2024 → 2025.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/charts/offtake-map.vl.json) #### How we know The notebook ran **14 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | 2024 cattle stock: cube = CSV | 12,138,148 | 12,138,148 | exactly | | 2024 cattle births: cube = CSV | 2,364,279 | 2,364,279 | exactly | | 2024 cattle deaths: cube = CSV | 264,496 | 264,496 | exactly | | 2024 cattle consumption: cube = CSV | 23,069 | 23,069 | exactly | | 2025 cattle stock: cube = CSV | 12,265,269 | 12,265,269 | exactly | | 2025 cattle births: cube = CSV | 2,697,988 | 2,697,988 | exactly | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) - Download: [herd-ledger.ipynb](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/herd-ledger.ipynb) (also in this workspace: file [`ipynb-herd-ledger`](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/herd-ledger.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.md) Reading path: previous: [*One year on, 2024 to 2025*](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md); next: [*Finding other Uruguay data*](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "The herd ledger", "abstract": "Uruguay's cattle books balance only if 2,300,543 head left the farms between the 2024 and 2025 declarations: 18.95% of the opening herd. Calves born (2,697,988) outran deaths (247,498), home slaughter (22,826) and the herd's own growth (+127,121).", "url": "https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/herd-ledger/herd-ledger.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md) - Next in the reading path: [Finding other Uruguay data](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md) - Related: [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-herd-ledger` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/) --- ### Finding other Uruguay data **Against the 2011 census (the latest by department in the catalogue's file), Uruguay has 3.73 cattle per person. In Durazno it is 16.7; in Montevideo, 0.0021. The dataset was found by meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes.** #### Charts ![Map: cattle per person is highest in Durazno, Florida and Flores (about 16), near zero in Montevideo.](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/charts/cattle-per-person-map.png) *Cattle per person, by department.* [Interactive](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) · [Vega-Lite spec](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/charts/cattle-per-person-map.vl.json) #### How we know The notebook ran **6 cross-checks**, every one passed; the build refuses to publish a notebook whose numbers disagree with the source. A sample: | check | got | expected | rule | | --- | --- | --- | --- | | semantic search finds the people-by-department census dataset, with a CSV, in its top ten | True | True | exactly | | …and ranks it in the top five | True | True | exactly | | 2011 census rows join all 19 departments | 19 | 19 | exactly | | the by-sex census table is among the search hits, with a CSV | True | True | exactly | | 2011 people per department: by-department table = by-sex table (total difference) | 0 | 0 | exactly | | 2025 cattle total after the join | 12,265,269 | 12,265,269 | exactly | Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) - Download: [finding-other-data.ipynb](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/finding-other-data.ipynb) (also in this workspace: file [`ipynb-finding-other-data`](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/finding-other-data.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.md) Reading path: previous: [*The herd ledger*](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md); next: [*Ask the agent*](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "Finding other Uruguay data", "abstract": "Against the 2011 census (the latest by department in the catalogue's file), Uruguay has 3.73 cattle per person. In Durazno it is 16.7; in Montevideo, 0.0021. The dataset was found by meaning in the catalogue graph, fetched from the link its DCAT record gives, and joined on the department codes.", "url": "https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/finding-other-data/finding-other-data.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [The herd ledger](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md) - Next in the reading path: [Ask the agent](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md) - Related: [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-finding-other-data` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/) --- ### Ask the agent Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. > This notebook is published unexecuted: it needs a service the build does not run. #### How we know Data: MGAP/SNIG DICOSE sworn declarations 2024 and 2025 (graph `uruguay-cows`), via SPARQL and MCP on the demo's own endpoint. #### The notebook - Read it: [https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) - Download: [ask-the-agent.ipynb](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/ask-the-agent.ipynb) (also in this workspace: file [`ipynb-ask-the-agent`](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/ask-the-agent.ipynb) in *Notebook files*) - For agents: [index.md](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.md) Reading path: previous: [*Finding other Uruguay data*](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md). The whole path: [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). #### Metadata ```json { "@context": "https://schema.org", "@type": [ "CreativeWork", "SoftwareSourceCode" ], "name": "Ask the agent", "abstract": "Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube.", "url": "https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html", "programmingLanguage": "Python", "license": "https://creativecommons.org/licenses/by/4.0/", "creditText": "cow-tools, Sophia Labs", "encoding": [ { "@type": "MediaObject", "contentUrl": "https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/ask-the-agent.ipynb", "encodingFormat": "application/x-ipynb+json" } ], "isBasedOn": { "@type": "Dataset", "name": "DICOSE – SNIG sworn livestock declarations 2024–2025", "url": "https://catalogodatos.gub.uy/dataset/mgap-datos-preliminares-basados-en-la-declaracion-jurada-de-existencias-dicose-snig-2025" } } ``` #### Connected (the graph's wires) - Previous in the reading path: [Finding other Uruguay data](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Notebooks: https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `notebook-ask-the-agent` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md · page: https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/) --- ### Artigas **Artigas declared 742,198 cattle on 30 June 2025, the 7th largest herd of Uruguay's 19 departments (+1.6% on 2024), 801,403 sheep, and 0.0% of the national milk.** ![Artigas highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/artigas.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 742,198 | 7 | +1.6% | | of which dairy cattle | 265 | | | | Sheep | 801,403 | 2 | -9.8% | | Sheep share of cattle + sheep | 51.9% | | | | Milk, litres | 390,931 | 18 | | | Livestock land, ha | 1,133,715 | | | | Cattle per livestock ha | 0.65 | 19 | | | Land under sown pasture | 2.2% | 19 | | | Beef herd: breeding cows + calves | 64.4% | 12 | | | Beef herd: steers + fattening cows | 21.1% | 7 | | | Offtake, 2024 → 2025 (inferred) | 138,861 (19.0%) | 9 | | | Holders declaring beef cattle | 2,594 | | | | Census areas with holdings | 27 | | | #### Notable - Artigas has the lowest stocking density of the 19 departments (0.65 cattle per livestock ha). - Artigas has the least land under sown pasture of the 19 departments (2.2%). - Artigas has more sheep than cattle by heads (51.9% sheep). #### Neighbours Artigas borders [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 1, ISO 3166-2 UY-AR, Wikidata Q16603), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Artigas", "identifier": [ "DICOSE:1", "UY-AR" ], "sameAs": "https://www.wikidata.org/wiki/Q16603", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 742198 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 801403 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 390931 } ] } ``` #### Connected (the graph's wires) - Borders: [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md) - Mentioned in: [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md), [How hard the land is stocked](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-artigas/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-artigas` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-artigas/index.md · page: https://cow-tools.sophia-labs.com/guide/department-artigas/) --- ### Canelones **Canelones declared 338,601 cattle on 30 June 2025, the 17th largest herd of Uruguay's 19 departments (-4.8% on 2024), 50,487 sheep, and 4.9% of the national milk.** ![Canelones highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/canelones.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 338,601 | 17 | -4.8% | | of which dairy cattle | 34,989 | | | | Sheep | 50,487 | 16 | -4.1% | | Sheep share of cattle + sheep | 13.0% | | | | Milk, litres | 112,534,896 | 6 | | | Livestock land, ha | 243,465 | | | | Cattle per livestock ha | 1.39 | 3 | | | Land under sown pasture | 17.2% | 3 | | | Beef herd: breeding cows + calves | 60.1% | 16 | | | Beef herd: steers + fattening cows | 22.6% | 4 | | | Offtake, 2024 → 2025 (inferred) | 58,553 (16.5%) | 14 | | | Holders declaring beef cattle | 4,717 | | | | Census areas with holdings | 133 | | | #### Notable - Canelones has the largest fall in cattle of the 19 departments (-4.8%). #### Neighbours Canelones borders [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 2, ISO 3166-2 UY-CA, Wikidata Q16577), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Canelones", "identifier": [ "DICOSE:2", "UY-CA" ], "sameAs": "https://www.wikidata.org/wiki/Q16577", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 338601 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 50487 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 112534896 } ] } ``` #### Connected (the graph's wires) - Borders: [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md) - Mentioned in: [How hard the land is stocked](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md), [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-canelones/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-canelones` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-canelones/index.md · page: https://cow-tools.sophia-labs.com/guide/department-canelones/) --- ### Cerro Largo **Cerro Largo declared 950,412 cattle on 30 June 2025, the 4th largest herd of Uruguay's 19 departments (-0.7% on 2024), 303,495 sheep, and 0.2% of the national milk.** ![Cerro Largo highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/cerro-largo.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 950,412 | 4 | -0.7% | | of which dairy cattle | 3,387 | | | | Sheep | 303,495 | 5 | -12.9% | | Sheep share of cattle + sheep | 24.2% | | | | Milk, litres | 5,677,767 | 14 | | | Livestock land, ha | 1,214,640 | | | | Cattle per livestock ha | 0.78 | 11 | | | Land under sown pasture | 4.0% | 15 | | | Beef herd: breeding cows + calves | 64.9% | 9 | | | Beef herd: steers + fattening cows | 20.5% | 9 | | | Offtake, 2024 → 2025 (inferred) | 216,665 (22.6%) | 3 | | | Holders declaring beef cattle | 4,453 | | | | Census areas with holdings | 37 | | | #### Neighbours Cerro Largo borders [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 3, ISO 3166-2 UY-CL, Wikidata Q16575), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Cerro Largo", "identifier": [ "DICOSE:3", "UY-CL" ], "sameAs": "https://www.wikidata.org/wiki/Q16575", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 950412 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 303495 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 5677767 } ] } ``` #### Connected (the graph's wires) - Borders: [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-cerro-largo/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-cerro-largo` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md · page: https://cow-tools.sophia-labs.com/guide/department-cerro-largo/) --- ### Colonia **Colonia declared 537,066 cattle on 30 June 2025, the 15th largest herd of Uruguay's 19 departments (-2.6% on 2024), 38,341 sheep, and 19.2% of the national milk.** ![Colonia highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/colonia.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 537,066 | 15 | -2.6% | | of which dairy cattle | 137,771 | | | | Sheep | 38,341 | 17 | -15.8% | | Sheep share of cattle + sheep | 6.7% | | | | Milk, litres | 441,387,725 | 3 | | | Livestock land, ha | 345,775 | | | | Cattle per livestock ha | 1.55 | 2 | | | Land under sown pasture | 22.8% | 2 | | | Beef herd: breeding cows + calves | 65.7% | 7 | | | Beef herd: steers + fattening cows | 18.3% | 12 | | | Offtake, 2024 → 2025 (inferred) | 92,680 (16.8%) | 13 | | | Holders declaring beef cattle | 2,695 | | | | Census areas with holdings | 43 | | | #### Notable - Colonia declares goat's milk: 31,150 litres in 2025. #### Neighbours Colonia borders [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 4, ISO 3166-2 UY-CO, Wikidata Q16580), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Colonia", "identifier": [ "DICOSE:4", "UY-CO" ], "sameAs": "https://www.wikidata.org/wiki/Q16580", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 537066 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 38341 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 441387725 } ] } ``` #### Connected (the graph's wires) - Borders: [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md) - Mentioned in: [Dairy country](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-colonia/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-colonia` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-colonia/index.md · page: https://cow-tools.sophia-labs.com/guide/department-colonia/) --- ### Durazno **Durazno declared 952,171 cattle on 30 June 2025, the 3rd largest herd of Uruguay's 19 departments (+5.8% on 2024), 290,920 sheep, and 9.2% of the national milk.** ![Durazno highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/durazno.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 952,171 | 3 | +5.8% | | of which dairy cattle | 33,190 | | | | Sheep | 290,920 | 6 | -13.1% | | Sheep share of cattle + sheep | 23.4% | | | | Milk, litres | 212,599,351 | 4 | | | Livestock land, ha | 981,607 | | | | Cattle per livestock ha | 0.97 | 7 | | | Land under sown pasture | 5.0% | 12 | | | Beef herd: breeding cows + calves | 64.9% | 10 | | | Beef herd: steers + fattening cows | 20.5% | 10 | | | Offtake, 2024 → 2025 (inferred) | 157,244 (17.5%) | 10 | | | Holders declaring beef cattle | 3,436 | | | | Census areas with holdings | 27 | | | #### Neighbours Durazno borders [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 5, ISO 3166-2 UY-DU, Wikidata Q16591), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Durazno", "identifier": [ "DICOSE:5", "UY-DU" ], "sameAs": "https://www.wikidata.org/wiki/Q16591", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 952171 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 290920 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 212599351 } ] } ``` #### Connected (the graph's wires) - Borders: [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) - Mentioned in: [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md), [Finding other Uruguay data](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-durazno/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-durazno` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-durazno/index.md · page: https://cow-tools.sophia-labs.com/guide/department-durazno/) --- ### Flores **Flores declared 409,429 cattle on 30 June 2025, the 16th largest herd of Uruguay's 19 departments (+4.1% on 2024), 83,001 sheep, and 2.5% of the national milk.** ![Flores highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/flores.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 409,429 | 16 | +4.1% | | of which dairy cattle | 18,843 | | | | Sheep | 83,001 | 13 | -13.0% | | Sheep share of cattle + sheep | 16.9% | | | | Milk, litres | 56,347,358 | 8 | | | Livestock land, ha | 407,512 | | | | Cattle per livestock ha | 1.00 | 6 | | | Land under sown pasture | 12.5% | 5 | | | Beef herd: breeding cows + calves | 60.6% | 15 | | | Beef herd: steers + fattening cows | 23.2% | 3 | | | Offtake, 2024 → 2025 (inferred) | 67,201 (17.1%) | 12 | | | Holders declaring beef cattle | 1,290 | | | | Census areas with holdings | 12 | | | #### Neighbours Flores borders [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 6, ISO 3166-2 UY-FS, Wikidata Q16578), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Flores", "identifier": [ "DICOSE:6", "UY-FS" ], "sameAs": "https://www.wikidata.org/wiki/Q16578", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 409429 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 83001 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 56347358 } ] } ``` #### Connected (the graph's wires) - Borders: [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-flores/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-flores` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-flores/index.md · page: https://cow-tools.sophia-labs.com/guide/department-flores/) --- ### Florida **Florida declared 1,117,097 cattle on 30 June 2025, the largest herd of Uruguay's 19 departments (+2.0% on 2024), 202,434 sheep, and 26.5% of the national milk.** ![Florida highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/florida.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 1,117,097 | 1 | +2.0% | | of which dairy cattle | 182,610 | | | | Sheep | 202,434 | 8 | -11.4% | | Sheep share of cattle + sheep | 15.3% | | | | Milk, litres | 608,116,907 | 1 | | | Livestock land, ha | 942,195 | | | | Cattle per livestock ha | 1.19 | 4 | | | Land under sown pasture | 14.2% | 4 | | | Beef herd: breeding cows + calves | 67.7% | 4 | | | Beef herd: steers + fattening cows | 14.9% | 18 | | | Offtake, 2024 → 2025 (inferred) | 169,868 (15.5%) | 16 | | | Holders declaring beef cattle | 3,731 | | | | Census areas with holdings | 31 | | | #### Notable - Florida has the most cattle of the 19 departments (1,117,097). - Florida has the most milk of the 19 departments (608,116,907 litres). #### Neighbours Florida borders [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 7, ISO 3166-2 UY-FD, Wikidata Q16593), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Florida", "identifier": [ "DICOSE:7", "UY-FD" ], "sameAs": "https://www.wikidata.org/wiki/Q16593", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 1117097 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 202434 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 608116907 } ] } ``` #### Connected (the graph's wires) - Borders: [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) - Mentioned in: [The national herd at a glance](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md), [Dairy country](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-florida/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-florida` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-florida/index.md · page: https://cow-tools.sophia-labs.com/guide/department-florida/) --- ### Lavalleja **Lavalleja declared 654,451 cattle on 30 June 2025, the 9th largest herd of Uruguay's 19 departments (+1.6% on 2024), 261,086 sheep, and 0.6% of the national milk.** ![Lavalleja highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/lavalleja.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 654,451 | 9 | +1.6% | | of which dairy cattle | 4,630 | | | | Sheep | 261,086 | 7 | -9.9% | | Sheep share of cattle + sheep | 28.5% | | | | Milk, litres | 13,893,232 | 12 | | | Livestock land, ha | 853,971 | | | | Cattle per livestock ha | 0.77 | 12 | | | Land under sown pasture | 5.3% | 10 | | | Beef herd: breeding cows + calves | 67.3% | 5 | | | Beef herd: steers + fattening cows | 17.8% | 13 | | | Offtake, 2024 → 2025 (inferred) | 127,726 (19.8%) | 6 | | | Holders declaring beef cattle | 4,683 | | | | Census areas with holdings | 40 | | | #### Notable - Lavalleja declares goat's milk: 10,320 litres in 2025. #### Neighbours Lavalleja borders [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 8, ISO 3166-2 UY-LA, Wikidata Q460435), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Lavalleja", "identifier": [ "DICOSE:8", "UY-LA" ], "sameAs": "https://www.wikidata.org/wiki/Q460435", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 654451 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 261086 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 13893232 } ] } ``` #### Connected (the graph's wires) - Borders: [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-lavalleja/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-lavalleja` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md · page: https://cow-tools.sophia-labs.com/guide/department-lavalleja/) --- ### Maldonado **Maldonado declared 234,191 cattle on 30 June 2025, the 18th largest herd of Uruguay's 19 departments (+1.6% on 2024), 101,340 sheep, and 0.6% of the national milk.** ![Maldonado highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/maldonado.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 234,191 | 18 | +1.6% | | of which dairy cattle | 3,854 | | | | Sheep | 101,340 | 12 | -6.1% | | Sheep share of cattle + sheep | 30.2% | | | | Milk, litres | 14,463,087 | 11 | | | Livestock land, ha | 351,186 | | | | Cattle per livestock ha | 0.67 | 18 | | | Land under sown pasture | 4.7% | 14 | | | Beef herd: breeding cows + calves | 71.7% | 1 | | | Beef herd: steers + fattening cows | 13.2% | 19 | | | Offtake, 2024 → 2025 (inferred) | 47,540 (20.6%) | 5 | | | Holders declaring beef cattle | 2,705 | | | | Census areas with holdings | 30 | | | #### Notable - Maldonado has the most breeding-heavy beef herd of the 19 departments (71.7% breeding cows and calves). - Maldonado has the smallest share of steers and fattening cows of the 19 departments (13.2%). - Maldonado declares goat's milk: 81,750 litres in 2025. - Maldonado declared 14,803 horses (a reference figure DICOSE does not quality-control), 6.3% of its cattle count. #### Neighbours Maldonado borders [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 9, ISO 3166-2 UY-MA, Wikidata Q331196), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Maldonado", "identifier": [ "DICOSE:9", "UY-MA" ], "sameAs": "https://www.wikidata.org/wiki/Q331196", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 234191 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 101340 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 14463087 } ] } ``` #### Connected (the graph's wires) - Borders: [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md) - Mentioned in: [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-maldonado/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-maldonado` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md · page: https://cow-tools.sophia-labs.com/guide/department-maldonado/) --- ### Montevideo **Montevideo declared 2,736 cattle on 30 June 2025, the 19th largest herd of Uruguay's 19 departments (+1.4% on 2024), 2,369 sheep, and 0.0% of the national milk.** ![Montevideo highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/montevideo.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 2,736 | 19 | +1.4% | | of which dairy cattle | 227 | | | | Sheep | 2,369 | 19 | -0.4% | | Sheep share of cattle + sheep | 46.4% | | | | Milk, litres | 111,160 | 19 | | | Livestock land, ha | 2,980 | | | | Cattle per livestock ha | 0.92 | 8 | | | Land under sown pasture | 5.3% | 9 | | | Beef herd: breeding cows + calves | 58.1% | 18 | | | Beef herd: steers + fattening cows | 20.8% | 8 | | | Offtake, 2024 → 2025 (inferred) | 129 (4.8%) | 19 | | | Holders declaring beef cattle | 146 | | | | Census areas with holdings | 14 | | | #### Notable - Montevideo has the fewest cattle of the 19 departments (2,736). - Montevideo has the fewest sheep of the 19 departments (2,369). - Montevideo has the least milk of the 19 departments (111,160 litres). - Montevideo has the lowest offtake rate of the 19 departments (4.8% of its opening herd). - Montevideo has the gentlest change in sheep of the 19 departments (-0.4%). - Montevideo declared 1,754 horses (a reference figure DICOSE does not quality-control), 64.1% of its cattle count. #### Neighbours Montevideo borders [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 10, ISO 3166-2 UY-MO, Wikidata Q1335), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Montevideo", "identifier": [ "DICOSE:10", "UY-MO" ], "sameAs": "https://www.wikidata.org/wiki/Q1335", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 2736 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 2369 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 111160 } ] } ``` #### Connected (the graph's wires) - Borders: [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [San José](https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md) - Mentioned in: [The national herd at a glance](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md), [The herd ledger](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md), [Finding other Uruguay data](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-montevideo/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-montevideo` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md · page: https://cow-tools.sophia-labs.com/guide/department-montevideo/) --- ### Paysandú **Paysandú declared 801,512 cattle on 30 June 2025, the 6th largest herd of Uruguay's 19 departments (-1.0% on 2024), 555,079 sheep, and 2.3% of the national milk.** ![Paysandú highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/paysandu.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 801,512 | 6 | -1.0% | | of which dairy cattle | 17,544 | | | | Sheep | 555,079 | 3 | -14.9% | | Sheep share of cattle + sheep | 40.9% | | | | Milk, litres | 52,582,414 | 9 | | | Livestock land, ha | 1,180,985 | | | | Cattle per livestock ha | 0.68 | 17 | | | Land under sown pasture | 4.8% | 13 | | | Beef herd: breeding cows + calves | 63.7% | 13 | | | Beef herd: steers + fattening cows | 21.3% | 6 | | | Offtake, 2024 → 2025 (inferred) | 179,667 (22.2%) | 4 | | | Holders declaring beef cattle | 3,318 | | | | Census areas with holdings | 29 | | | #### Notable - Paysandú declares goat's milk: 3,500 litres in 2025. #### Neighbours Paysandú borders [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 11, ISO 3166-2 UY-PA, Wikidata Q16576), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Paysandú", "identifier": [ "DICOSE:11", "UY-PA" ], "sameAs": "https://www.wikidata.org/wiki/Q16576", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 801512 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 555079 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 52582414 } ] } ``` #### Connected (the graph's wires) - Borders: [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-paysandu/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-paysandu` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md · page: https://cow-tools.sophia-labs.com/guide/department-paysandu/) --- ### Rivera **Rivera declared 639,917 cattle on 30 June 2025, the 10th largest herd of Uruguay's 19 departments (+5.2% on 2024), 182,585 sheep, and 0.2% of the national milk.** ![Rivera highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/rivera.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 639,917 | 10 | +5.2% | | of which dairy cattle | 1,801 | | | | Sheep | 182,585 | 9 | -9.4% | | Sheep share of cattle + sheep | 22.2% | | | | Milk, litres | 4,399,756 | 15 | | | Livestock land, ha | 770,887 | | | | Cattle per livestock ha | 0.83 | 10 | | | Land under sown pasture | 3.3% | 16 | | | Beef herd: breeding cows + calves | 67.0% | 6 | | | Beef herd: steers + fattening cows | 16.7% | 16 | | | Offtake, 2024 → 2025 (inferred) | 96,461 (15.9%) | 15 | | | Holders declaring beef cattle | 3,635 | | | | Census areas with holdings | 32 | | | #### Notable - Rivera declared 34,588 horses (a reference figure DICOSE does not quality-control), 5.4% of its cattle count. #### Neighbours Rivera borders [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 13, ISO 3166-2 UY-RV, Wikidata Q16609), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Rivera", "identifier": [ "DICOSE:13", "UY-RV" ], "sameAs": "https://www.wikidata.org/wiki/Q16609", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 639917 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 182585 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 4399756 } ] } ``` #### Connected (the graph's wires) - Borders: [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md) - Mentioned in: [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-rivera/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-rivera` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-rivera/index.md · page: https://cow-tools.sophia-labs.com/guide/department-rivera/) --- ### Rocha **Rocha declared 682,644 cattle on 30 June 2025, the 8th largest herd of Uruguay's 19 departments (-0.8% on 2024), 154,813 sheep, and 0.5% of the national milk.** ![Rocha highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/rocha.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 682,644 | 8 | -0.8% | | of which dairy cattle | 4,236 | | | | Sheep | 154,813 | 11 | -8.8% | | Sheep share of cattle + sheep | 18.5% | | | | Milk, litres | 11,083,888 | 13 | | | Livestock land, ha | 903,944 | | | | Cattle per livestock ha | 0.76 | 13 | | | Land under sown pasture | 8.0% | 8 | | | Beef herd: breeding cows + calves | 67.8% | 3 | | | Beef herd: steers + fattening cows | 17.5% | 14 | | | Offtake, 2024 → 2025 (inferred) | 174,553 (25.4%) | 2 | | | Holders declaring beef cattle | 3,421 | | | | Census areas with holdings | 34 | | | #### Neighbours Rocha borders [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 14, ISO 3166-2 UY-RO, Wikidata Q16582), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Rocha", "identifier": [ "DICOSE:14", "UY-RO" ], "sameAs": "https://www.wikidata.org/wiki/Q16582", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 682644 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 154813 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 11083888 } ] } ``` #### Connected (the graph's wires) - Borders: [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Maldonado](https://cow-tools.sophia-labs.com/guide/department-maldonado/index.md), [Treinta y Tres](https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md) - Mentioned in: [The herd ledger](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-rocha/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-rocha` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-rocha/index.md · page: https://cow-tools.sophia-labs.com/guide/department-rocha/) --- ### Río Negro **Río Negro declared 549,369 cattle on 30 June 2025, the 13th largest herd of Uruguay's 19 departments (-1.2% on 2024), 69,144 sheep, and 3.6% of the national milk.** ![Río Negro highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/rio-negro.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 549,369 | 13 | -1.2% | | of which dairy cattle | 24,277 | | | | Sheep | 69,144 | 14 | -18.3% | | Sheep share of cattle + sheep | 11.2% | | | | Milk, litres | 82,430,061 | 7 | | | Livestock land, ha | 627,764 | | | | Cattle per livestock ha | 0.88 | 9 | | | Land under sown pasture | 9.8% | 7 | | | Beef herd: breeding cows + calves | 58.3% | 17 | | | Beef herd: steers + fattening cows | 26.2% | 2 | | | Offtake, 2024 → 2025 (inferred) | 106,598 (19.2%) | 8 | | | Holders declaring beef cattle | 1,831 | | | | Census areas with holdings | 17 | | | #### Notable - Río Negro has the steepest fall in sheep of the 19 departments (-18.3%). #### Neighbours Río Negro borders [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Paysandú](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 12, ISO 3166-2 UY-RN, Wikidata Q16596), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Río Negro", "identifier": [ "DICOSE:12", "UY-RN" ], "sameAs": "https://www.wikidata.org/wiki/Q16596", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 549369 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 69144 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 82430061 } ] } ``` #### Connected (the graph's wires) - Borders: [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Paysandú](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md), [Soriano](https://cow-tools.sophia-labs.com/guide/department-soriano/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md) - Mentioned in: [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-rio-negro/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-rio-negro` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md · page: https://cow-tools.sophia-labs.com/guide/department-rio-negro/) --- ### Salto **Salto declared 898,899 cattle on 30 June 2025, the 5th largest herd of Uruguay's 19 departments (+5.9% on 2024), 1,032,181 sheep, and 0.9% of the national milk.** ![Salto highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/salto.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 898,899 | 5 | +5.9% | | of which dairy cattle | 8,591 | | | | Sheep | 1,032,181 | 1 | -10.3% | | Sheep share of cattle + sheep | 53.5% | | | | Milk, litres | 21,769,982 | 10 | | | Livestock land, ha | 1,323,035 | | | | Cattle per livestock ha | 0.68 | 16 | | | Land under sown pasture | 2.3% | 18 | | | Beef herd: breeding cows + calves | 64.6% | 11 | | | Beef herd: steers + fattening cows | 19.6% | 11 | | | Offtake, 2024 → 2025 (inferred) | 146,395 (17.2%) | 11 | | | Holders declaring beef cattle | 3,179 | | | | Census areas with holdings | 32 | | | #### Notable - Salto has the most sheep of the 19 departments (1,032,181). - Salto has the largest rise in cattle of the 19 departments (+5.9%). - Salto has more sheep than cattle by heads (53.5% sheep). #### Neighbours Salto borders [Artigas](https://cow-tools.sophia-labs.com/guide/department-artigas/index.md), [Paysandú](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 15, ISO 3166-2 UY-SA, Wikidata Q16595), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Salto", "identifier": [ "DICOSE:15", "UY-SA" ], "sameAs": "https://www.wikidata.org/wiki/Q16595", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 898899 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 1032181 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 21769982 } ] } ``` #### Connected (the graph's wires) - Borders: [Artigas](https://cow-tools.sophia-labs.com/guide/department-artigas/index.md), [Paysandú](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Tacuarembó](https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md) - Mentioned in: [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md), [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-salto/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-salto` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-salto/index.md · page: https://cow-tools.sophia-labs.com/guide/department-salto/) --- ### San José **San José declared 541,254 cattle on 30 June 2025, the 14th largest herd of Uruguay's 19 departments (-1.3% on 2024), 37,781 sheep, and 22.6% of the national milk.** ![San José highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/san-jose.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 541,254 | 14 | -1.3% | | of which dairy cattle | 164,033 | | | | Sheep | 37,781 | 18 | -15.2% | | Sheep share of cattle + sheep | 6.5% | | | | Milk, litres | 520,036,099 | 2 | | | Livestock land, ha | 324,103 | | | | Cattle per livestock ha | 1.67 | 1 | | | Land under sown pasture | 25.9% | 1 | | | Beef herd: breeding cows + calves | 65.2% | 8 | | | Beef herd: steers + fattening cows | 17.1% | 15 | | | Offtake, 2024 → 2025 (inferred) | 78,096 (14.2%) | 18 | | | Holders declaring beef cattle | 2,448 | | | | Census areas with holdings | 41 | | | #### Notable - San José has the highest stocking density of the 19 departments (1.67 cattle per livestock ha). - San José has the most land under sown pasture of the 19 departments (25.9%). - San José declares goat's milk: 191,350 litres in 2025. #### Neighbours San José borders [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Colonia](https://cow-tools.sophia-labs.com/guide/department-colonia/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 16, ISO 3166-2 UY-SJ, Wikidata Q16579), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "San José", "identifier": [ "DICOSE:16", "UY-SJ" ], "sameAs": "https://www.wikidata.org/wiki/Q16579", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 541254 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 37781 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 520036099 } ] } ``` #### Connected (the graph's wires) - Borders: [Canelones](https://cow-tools.sophia-labs.com/guide/department-canelones/index.md), [Colonia](https://cow-tools.sophia-labs.com/guide/department-colonia/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Montevideo](https://cow-tools.sophia-labs.com/guide/department-montevideo/index.md) - Mentioned in: [Dairy country](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md), [How hard the land is stocked](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md), [The herd ledger](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-san-jose/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-san-jose` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-san-jose/index.md · page: https://cow-tools.sophia-labs.com/guide/department-san-jose/) --- ### Soriano **Soriano declared 567,452 cattle on 30 June 2025, the 12th largest herd of Uruguay's 19 departments (-0.5% on 2024), 55,293 sheep, and 5.8% of the national milk.** ![Soriano highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/soriano.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 567,452 | 12 | -0.5% | | of which dairy cattle | 37,666 | | | | Sheep | 55,293 | 15 | -9.7% | | Sheep share of cattle + sheep | 8.9% | | | | Milk, litres | 132,200,132 | 5 | | | Livestock land, ha | 493,507 | | | | Cattle per livestock ha | 1.15 | 5 | | | Land under sown pasture | 12.5% | 6 | | | Beef herd: breeding cows + calves | 52.7% | 19 | | | Beef herd: steers + fattening cows | 29.8% | 1 | | | Offtake, 2024 → 2025 (inferred) | 81,530 (14.3%) | 17 | | | Holders declaring beef cattle | 2,473 | | | | Census areas with holdings | 28 | | | #### Notable - Soriano has the least breeding-heavy beef herd of the 19 departments (52.7% breeding cows and calves). - Soriano has the largest share of steers and fattening cows of the 19 departments (29.8%). #### Neighbours Soriano borders [Colonia](https://cow-tools.sophia-labs.com/guide/department-colonia/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 17, ISO 3166-2 UY-SO, Wikidata Q16584), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Soriano", "identifier": [ "DICOSE:17", "UY-SO" ], "sameAs": "https://www.wikidata.org/wiki/Q16584", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 567452 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 55293 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 132200132 } ] } ``` #### Connected (the graph's wires) - Borders: [Colonia](https://cow-tools.sophia-labs.com/guide/department-colonia/index.md), [Flores](https://cow-tools.sophia-labs.com/guide/department-flores/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md) - Mentioned in: [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-soriano/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-soriano` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-soriano/index.md · page: https://cow-tools.sophia-labs.com/guide/department-soriano/) --- ### Tacuarembó **Tacuarembó declared 1,061,136 cattle on 30 June 2025, the 2nd largest herd of Uruguay's 19 departments (+2.6% on 2024), 398,742 sheep, and 0.2% of the national milk.** ![Tacuarembó highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/tacuarembo.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 1,061,136 | 2 | +2.6% | | of which dairy cattle | 2,618 | | | | Sheep | 398,742 | 4 | -12.2% | | Sheep share of cattle + sheep | 27.3% | | | | Milk, litres | 4,025,047 | 17 | | | Livestock land, ha | 1,413,868 | | | | Cattle per livestock ha | 0.75 | 14 | | | Land under sown pasture | 2.6% | 17 | | | Beef herd: breeding cows + calves | 62.0% | 14 | | | Beef herd: steers + fattening cows | 21.9% | 5 | | | Offtake, 2024 → 2025 (inferred) | 199,859 (19.3%) | 7 | | | Holders declaring beef cattle | 5,246 | | | | Census areas with holdings | 35 | | | #### Neighbours Tacuarembó borders [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Paysandú](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 18, ISO 3166-2 UY-TA, Wikidata Q16587), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Tacuarembó", "identifier": [ "DICOSE:18", "UY-TA" ], "sameAs": "https://www.wikidata.org/wiki/Q16587", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 1061136 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 398742 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 4025047 } ] } ``` #### Connected (the graph's wires) - Borders: [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Paysandú](https://cow-tools.sophia-labs.com/guide/department-paysandu/index.md), [Rivera](https://cow-tools.sophia-labs.com/guide/department-rivera/index.md), [Río Negro](https://cow-tools.sophia-labs.com/guide/department-rio-negro/index.md), [Salto](https://cow-tools.sophia-labs.com/guide/department-salto/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-tacuarembo/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-tacuarembo` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-tacuarembo/index.md · page: https://cow-tools.sophia-labs.com/guide/department-tacuarembo/) --- ### Treinta y Tres **Treinta y Tres declared 584,734 cattle on 30 June 2025, the 11th largest herd of Uruguay's 19 departments (-4.6% on 2024), 178,572 sheep, and 0.2% of the national milk.** ![Treinta y Tres highlighted on a map of Uruguay's departments](https://cow-tools.sophia-labs.com/notebooks/departments/treinta-y-tres.png) | 2025 | value | rank of 19 | change on 2024 | | --- | --- | --- | --- | | Cattle (beef + dairy) | 584,734 | 11 | -4.6% | | of which dairy cattle | 1,416 | | | | Sheep | 178,572 | 10 | -14.2% | | Sheep share of cattle + sheep | 23.4% | | | | Milk, litres | 4,352,525 | 16 | | | Livestock land, ha | 806,168 | | | | Cattle per livestock ha | 0.73 | 15 | | | Land under sown pasture | 5.0% | 11 | | | Beef herd: breeding cows + calves | 69.8% | 2 | | | Beef herd: steers + fattening cows | 15.3% | 17 | | | Offtake, 2024 → 2025 (inferred) | 160,917 (26.2%) | 1 | | | Holders declaring beef cattle | 3,120 | | | | Census areas with holdings | 25 | | | #### Notable - Treinta y Tres has the highest offtake rate of the 19 departments (26.2% of its opening herd). #### Neighbours Treinta y Tres borders [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md). Computed from the Natural Earth outlines (departments sharing more than 5 km of boundary). #### In the notebooks - [The national herd at a glance](https://cow-tools.sophia-labs.com/notebooks/national-herd/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-national-herd/index.md)): How many animals Uruguay's farms declared in 2025, by species and by department, to the head. - [Cattle and sheep, department by department](https://cow-tools.sophia-labs.com/notebooks/cattle-and-sheep/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-cattle-and-sheep/index.md)): Where Uruguay is a sheep country and where it is a cattle country, and how one year's fall in sheep shows up on the map. - [Dairy country](https://cow-tools.sophia-labs.com/notebooks/dairy-country/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-dairy-country/index.md)): The cuenca lechera of Florida, San José and Colonia: how much milk, how many dairy cows, and which is the most intensive. - [Breeders in the east, finishers in the west](https://cow-tools.sophia-labs.com/notebooks/herd-structure/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-structure/index.md)): What the mix of cows, calves and steers says about each department's place in the beef chain. - [How hard the land is stocked](https://cow-tools.sophia-labs.com/notebooks/stocking-intensity/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-stocking-intensity/index.md)): Cattle per hectare of livestock land, by department and by census area, and why it follows the sown pastures. - [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/notebooks/year-over-year/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md)): What changed between two sworn declarations, department by department, with the data's own quality warnings read first. - [The herd ledger](https://cow-tools.sophia-labs.com/notebooks/herd-ledger/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md)): Balancing Uruguay's cattle like a set of books: births in, deaths and home slaughter out, and the 2.3 million head that must have left. - [Finding other Uruguay data](https://cow-tools.sophia-labs.com/notebooks/finding-other-data/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-finding-other-data/index.md)): Search the national open-data catalogue by meaning, pull the dataset it finds, and join it to the herd on the department spine: cattle per person. - [Ask the agent](https://cow-tools.sophia-labs.com/notebooks/ask-the-agent/index.html) ([in the guide](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md)): Start a personal agent over the herd data from Python, with your own OpenRouter key, and check its answer against the cube. #### Where these numbers come from SPARQL over the graph `uruguay-cows` (DICOSE code 19, ISO 3166-2 UY-TT, Wikidata Q16610), from the 2025 sworn declarations (and 2024 for changes). Before this page was written, its cattle, sheep, milk and land figures were checked against the original CSVs for all 19 departments. Stock is PD_AD (animals on the holding). Offtake is births − deaths − home slaughter − the change in stock, so it includes cattle sold to other departments. #### Metadata ```json { "@context": "https://schema.org", "@type": "AdministrativeArea", "name": "Treinta y Tres", "identifier": [ "DICOSE:19", "UY-TT" ], "sameAs": "https://www.wikidata.org/wiki/Q16610", "containedInPlace": { "@type": "Country", "name": "Uruguay" }, "additionalProperty": [ { "@type": "PropertyValue", "name": "cattle (DICOSE, 30 June 2025)", "value": 584734 }, { "@type": "PropertyValue", "name": "sheep (DICOSE, 30 June 2025)", "value": 178572 }, { "@type": "PropertyValue", "name": "milk litres (DICOSE 2025)", "value": 4352525 } ] } ``` #### Connected (the graph's wires) - Borders: [Cerro Largo](https://cow-tools.sophia-labs.com/guide/department-cerro-largo/index.md), [Durazno](https://cow-tools.sophia-labs.com/guide/department-durazno/index.md), [Florida](https://cow-tools.sophia-labs.com/guide/department-florida/index.md), [Lavalleja](https://cow-tools.sophia-labs.com/guide/department-lavalleja/index.md), [Rocha](https://cow-tools.sophia-labs.com/guide/department-rocha/index.md) - Mentioned in: [One year on, 2024 to 2025](https://cow-tools.sophia-labs.com/guide/notebook-year-over-year/index.md), [The herd ledger](https://cow-tools.sophia-labs.com/guide/notebook-herd-ledger/index.md) --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Departments: https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `department-treinta-y-tres` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/index.md · page: https://cow-tools.sophia-labs.com/guide/department-treinta-y-tres/) --- ### What DICOSE is Every year, everyone in Uruguay who holds livestock tells the state how many animals they hold. Not roughly. Under oath. The oath is the **Declaración Jurada de Existencias** (the sworn declaration of stock), and the office that receives it is **DICOSE**, the División de Contralor de Semovientes of the Ministerio de Ganadería, Agricultura y Pesca (MGAP). The ministry's livestock information system, **SNIG** (Sistema Nacional de Información Ganadera), publishes the declarations each year on the national open-data catalogue, aggregated so that no single holder can be seen, as a folder of semicolon-separated files in Latin-1. This graph holds two of those years: the declaration years (*ejercicios*) **2024** and **2025**. The datasets, as the catalogue names them: - *Datos actualizados Declaración jurada de Existencias DICOSE – SNIG 2024* (publisher MGAP, modified 2026-06-10); - *Datos Actualizados de la Declaración Jurada de Existencias DICOSE – SNIG 2025* (publisher MGAP, modified 2026-06-17). Both are published under the Licencia de Datos Abiertos – Uruguay. Every number this guide quotes comes from them, and the source graph of `uruguay-cows` records which file, by name and sha256, each observation came from. #### What is declared A holder files forms (A1 for the establishment, its land and its herd; A3 to A6 for the detail by species, with the milk in A3 and A6), and SNIG rolls them up. The published tables, and what cow-tools made of each: | File | What it holds | In the graph as | | --- | --- | --- | | `datosgenerales.csv` | per group of holders: total and livestock hectares, livestock units, number of holders | `cow:GeneralHoldingObservation` | | `datosanimales.csv` | animals per species, with births, deaths and animals consumed on the farm | `cow:AnimalFlowObservation` | | `datosanimalesdetallados.csv` | animals per species **and category** (bulls, breeding cows, steers by age, calves; milking cows, dry cows) | `cow:AnimalCategoryStockObservation` | | `usotierra.csv`, `tenenciatierra.csv`, `mejoramientostierras.csv` | hectares by land use, by tenure, by improvement | land observations | | `produccionleche.csv`, `produccionlecheestablecimiento.csv` | litres of milk produced, and processed on the farm | milk observations | | `codigos*.csv` | the code lists: departments, species, categories, activities, strata | SKOS concepts | A "group of holders" is one combination of department, police section (*seccional policial*), enumeration area (*área de enumeración*, the census geography of MGAP's statistics office DIEA), activity, line of business (*giro*), legal nature, size stratum, MGAP specialization and production type. That is the finest grain published: about 537,000 observations a year, none of them a farm. #### The species 1 beef cattle (*bovinos*), 2 sheep (*ovinos*), 3 horses (*yeguarizos*), 4 goats (*caprinos*), 5 pigs (*suinos*), 10 poultry (*aves*, in the code list only), 11 dairy cattle (*bovinos de leche*). Uruguay's cattle are species 1 plus species 11. MGAP itself says the pig, goat and horse counts are included "as a reference", without its quality controls. #### What it is not It is not a register of animals. There are no ear tags, no owners, no movements, no DICOSE numbers in the public files, and cow-tools refuses any source that carries one (its ingest checks every column header before a single triple is written). If you need an individual cow, you need a different country's open data, or a farm. #### Why anyone would want to know this much about Uruguay Uruguay has about 3.4 million people and, in 2025, 12,265,269 head of cattle: some three and a half cows per person, each of them sworn to. The country also counted 2,736 cattle in the department of Montevideo, which is mostly a capital city. The curated tools will tell you where each of the others is, by category and by enumeration area, and the guide called *Questions with exact answers* shows how. --- *This guide is by Sophia Labs, under CC BY 4.0. The data it describes is MGAP's (and, for the catalogue, each publisher's), under the Licencia de Datos Abiertos – Uruguay.* The cow-tools guide, The guide: https://cow-tools.sophia-labs.com/guide/what-is-dicose/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `what-is-dicose` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/what-is-dicose/index.md · page: https://cow-tools.sophia-labs.com/guide/what-is-dicose/) --- ### How to read the cubes The graph `uruguay-cows` is the DICOSE declarations of 2024 and 2025, every row of every published table, as RDF: a W3C **Data Cube** of observations, **PROV** for where each came from, **SKOS** for the code lists. Nothing was averaged away on the way in. There are two ways to read it: the curated `cow_*` tools, which know the shapes and the traps, and SPARQL, which knows nothing and will do anything. #### The curated tools first They answer the usual questions in one call, with provenance and warnings, and they refuse what they cannot answer rather than guess: | Question | Tool | | --- | --- | | How many animals of a species, by department and category? | `cow_herd` (`species`, `departments`, `categories`, `year`) | | Which departments have the most (or fewest) of something? National totals? | `cow_rank` (`metric`, `year`, `limit: 19` for every department) | | Everything about one department, or one enumeration area | `cow_area_profile` (`department` by name or code) | | This year against last year | `cow_compare` (`years: [2024, 2025]`, `metrics`, `entities`) | | What does a metric mean? | `cow_metric` | | Can I trust this year? | `cow_quality_report` (`year`) | | Where did this number come from? | `cow_sources`, `cow_report` with `reportId: source_provenance` | | A map | `cow_map` (`metric`, `year`) | Departments may be named ("Florida", "San José", "treinta y tres") or coded ("7"); species by code or plain name ("dairy cattle", "sheep"). An unknown name is refused with the list of known ones. A year the graph does not hold is refused. An argument a tool does not take is refused. Every call has a budget (20 seconds); a call that outlives it is cancelled and says so. #### The named graphs Each kind of thing lives in its own named graph, and SPARQL sees nothing unless you name the graph (wrap every pattern in `GRAPH <...> { }`, or `GRAPH ?g { }`): | Named graph | Holds | | --- | --- | | `urn:sophia:garden:uruguay-cows:cow:observations:2025` (and `:2024`) | the observations, one per published row | | `urn:sophia:garden:uruguay-cows:cow:derived:2025` | derived metrics per department and enumeration area (counts, sums, densities) | | `urn:sophia:garden:uruguay-cows:cow:codelists:2025` | departments, enumeration areas, species, categories and the other code lists, as SKOS concepts with their labels | | `urn:sophia:garden:uruguay-cows:cow:quality:2025` | that year's quality report: checks, violations, warnings | | `urn:sophia:garden:uruguay-cows:cow:sources` | provenance: the catalogue datasets, their files and download links, sha256s, row counts, the licence | | `urn:sophia:garden:uruguay-cows:cow:ontology` | the vocabulary (`https://sophia.dev/ontology/cattle-aggregates#`, prefix `cow:`) and its metric definitions | #### An observation Every observation is `a cow:AggregateObservation` plus one of `cow:GeneralHoldingObservation`, `cow:AnimalFlowObservation`, `cow:AnimalCategoryStockObservation`, the land observations, or the milk observations. Each carries its dimensions (`cow:year`, `cow:department`, `cow:enumerationArea`, `cow:species`, `cow:animalCategory`, and the strata: police section, activity, line of business, legal nature, size stratum, MGAP specialization and production type) and its measures: - `cow:animalsCount`: animals **PD+AD**, the holder's own animals inside the establishment plus other people's animals inside it. DICOSE's traditional count. - `cow:animalsCountPf`: animals **PD+PF**, the holder's own animals inside plus its own animals kept elsewhere. MGAP uses this one for the dairy herd. - `cow:holdersCount`, `cow:birthsCount`, `cow:deathsCount`, `cow:consumptionCount`, `cow:hectares`, `cow:milkLiters`, and their kin. The two animal counts differ, legitimately: animals grazing on someone else's land are counted where they stand in one and with their owner in the other. Say which you mean. Departments are `urn:sophia:cow:department/7` (Florida), species `urn:sophia:cow:species/11` (dairy cattle), categories `urn:sophia:cow:animal-category/11/2` (dairy cattle, milking cows). Category codes mean different things for different species (category 2 is breeding cows for beef cattle, milking cows for dairy cattle, breeding ewes for sheep), so the species is part of the category's address. #### The dairy cows of Florida, by hand ```sparql PREFIX cow: SELECT ?category (SUM(?pdad) AS ?animalsPdAd) (SUM(?pdpf) AS ?animalsPdPf) WHERE { GRAPH { ?obs a cow:AnimalCategoryStockObservation ; cow:department ; cow:species ; cow:animalCategory ?category ; cow:animalsCount ?pdad ; cow:animalsCountPf ?pdpf . VALUES ?category { } } } GROUP BY ?category ``` `cow_herd` with `species: "dairy cattle", department: "Florida", categories: ["2", "3"], year: 2025` does the same, with labels, both measures, the source rows counted and the file named. #### A derived metric, by hand ```sparql PREFIX cow: SELECT ?department ?value WHERE { GRAPH { ?obs a cow:DerivedMetricObservation ; cow:metric cow:metric_bovine_count ; cow:department ?department ; cow:metricValue ?value . FILTER NOT EXISTS { ?obs cow:animalCategory ?c } FILTER NOT EXISTS { ?obs cow:enumerationArea ?a } } } ORDER BY DESC(?value) ``` `bovine_count` is beef plus dairy cattle (species 1 and 11), PD+AD. The derived graph also holds per-enumeration-area values and per-category shares; filter for the level you want, or you will add departments to their own enumeration areas and be twice as impressed. #### Budgets gardend's own `sparql_query` runs every query under a deadline and a row ceiling (on the public endpoint 10 seconds and 1,000 rows; for the owner 30 seconds by default, `timeoutMs` up to 120,000, and 50,000 rows), and cancels the engine when either is reached. A query that joins two hundred thousand observations to two hundred thousand observations will be stopped and will say so. Narrow it: one year, one department, one species. --- *This guide is by Sophia Labs, under CC BY 4.0. The data it describes is MGAP's (and, for the catalogue, each publisher's), under the Licencia de Datos Abiertos – Uruguay.* The cow-tools guide, The guide: https://cow-tools.sophia-labs.com/guide/reading-the-cubes/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `reading-the-cubes` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/reading-the-cubes/index.md · page: https://cow-tools.sophia-labs.com/guide/reading-the-cubes/) --- ### Known caveats A sworn declaration is still a declaration. MGAP publishes a *limitantes conocidas* (known limitations) column beside every variable, and cow-tools keeps a quality report per year; both are here, in one place, so that nobody has to discover them at the bottom of a spreadsheet at two in the morning. #### Which count of animals There are two, and they are both right. - **PD+AD** (`animalsCount`): the holder's own animals inside the establishment plus other people's animals inside it. "The one traditionally used by DICOSE." - **PD+PF** (`animalsCountPf`): the holder's own animals inside plus its own animals kept somewhere else. MGAP: "used to measure the stock of cattle associated with dairy production." MGAP again: "the number of own animals outside does not match the number of others' animals inside, so the total stock can vary according to the criterion adopted." In 2025 the national beef herd is 11,583,321 by PD+AD and 11,734,888 by PD+PF. `cow_rank` and the derived metrics use PD+AD; `cow_herd` gives both and recommends PD+PF for dairy cattle. Name the measure with the number. #### Which species to believe "The stocks of pigs, goats and horses are included as a reference, since no quality controls have been applied to them." Cattle and sheep are checked; the others are what was declared. #### Where an animal is - **Department** is the department where the holder is *registered*, from the register of livestock holders. "In some cases there may be inconsistencies with the department of the enumeration area in which the establishment is classified." - **Enumeration area** is computed from the land parcels (*padrones*) the holder declares, DIEA's map of enumeration areas and the rural cadastre. "Not every producer declares parcels, not every parcel is in the rural cadastre," and an establishment spanning several areas is put in the largest. Rows that could not be placed carry area 0. - A department total and the sum of its enumeration areas need not agree. Do not add one to the other. #### Land - Total area is "the sum of hectares by tenure, except when that is zero, when the sum of land uses is used," and "there may be differences in some cases between the total area and its breakdown by tenure and by land use." - Livestock area excludes cropland, gardens, orchards, vineyards and 70% of planted forest. - Some establishments declare animals and no land (the size stratum 0, which also lets dairy farmers without land be seen). Densities per hectare are therefore null where the area is zero, never infinite. #### Dairy "Some cases of inconsistency have been identified between the breakdown of dairy cattle by category in form A3 and the total of cattle in the establishment in form A1." The category table and the species table can disagree slightly for dairy cattle; `cow_herd` reads the category table, `cow_rank`'s counts read the species table. #### Codes - Activity comes from the third and fourth digits of the holder's DICOSE number, as assigned at registration; "some isolated inconsistencies between the activity and the declared line of business have been detected." - Category codes are only unique within a species. Category 2 is breeding cows for beef cattle and milking cows for dairy cattle. cow-tools puts the species in the category's IRI so the two never meet. - The 2025 package does not publish every code list the 2024 one does. Where 2025 observations use a code whose list only 2024 publishes (MGAP production types), cow-tools borrows the 2024 list, says so in 2025's quality report, and records the borrow as provenance. It never borrows silently. - The files are Latin-1 with semicolons and decimal commas. cow-tools decodes them; a tool that reads them as UTF-8 will find "A�OS" where there should be "AÑOS". #### Years Two years are loaded: 2024 and 2025. The tools refuse any other. The 2025 package is "Datos Actualizados" (updated data), last modified on 17 June 2026; MGAP has revised these packages before and may again, and the source graph records the sha256 of every file used, so a later revision can be told apart. #### What the quality report says `cow_quality_report` with a `year` returns that year's checks, read from the RDF: whether the year passed (both did, with no blocking violations), the warnings, and the violations. The individual-record gate is part of it: an extract carrying a DICOSE number, an owner or an animal identifier is refused before anything is written, and the RDF is re-scanned for such predicates afterwards. #### What the tools will not do They will not guess a department from a misspelling, average two measures, extrapolate a year, or answer from a cache that might differ from the RDF (a cached report is served only when its parameters match exactly; otherwise the answer says it fell back to SPARQL). When they cannot answer, they say why. --- *This guide is by Sophia Labs, under CC BY 4.0. The data it describes is MGAP's (and, for the catalogue, each publisher's), under the Licencia de Datos Abiertos – Uruguay.* The cow-tools guide, The guide: https://cow-tools.sophia-labs.com/guide/caveats/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `caveats` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/caveats/index.md · page: https://cow-tools.sophia-labs.com/guide/caveats/) --- ### Finding other Uruguay data Cows are a beginning. Uruguay's national open-data catalogue, catalogodatos.gub.uy, lists 2,718 datasets from 70 publishers (harvested on 14 October 2026), and the graph `uruguay-catalogue` holds every one of them: title, description, publisher, themes, keywords, licence, dates, and each of their 14,426 files with its download link. Of the 2,718, 1,875 come from the Ministerio de Desarrollo Social (MIDES), most of them one indicator each; the Intendencia de Montevideo has 159, ANCAP 60, the national post office 43. Somebody, somewhere, has published the readings of a meteorological buoy, the price of fuel at the refinery gate, and the number of women mayors in each department. They are all here, waiting. #### By meaning The graph's documents are cards: one per publisher (MIDES needs thirteen), one paragraph per dataset. Each paragraph has the Spanish title, an English gloss of it, the publisher's description, themes in both languages, the file formats, the last modified date, and the dataset's IRI. Semantic search runs over those paragraphs, so a question in either language finds them: ``` semantic_search graphId: uruguay-catalogue query: "electricity consumption by department" semantic_search graphId: uruguay-catalogue query: "consumo de energía" semantic_search graphId: uruguay-catalogue query: "school enrolment" ``` Each hit's `content` ends with `Dataset : >`. That IRI is the dataset in the DCAT graph. Search finds what exists, which is not always what was asked for. There is, for instance, no series of electricity consumption by department on the catalogue: the national energy balance (MIEM's *Balance Energético Nacional*, BEN) gives consumption by sector and by source for the whole country, and MIDES gives the share of households without electricity by department. A good answer says so, and offers both. The English glosses are Sophia's translations of the titles, not the publishers'. They exist because the semantic model is better at English than at Spanish; the Spanish is always beside them, and it is the Spanish that is official. #### By name or publisher `search_documents` matches card titles (publishers), and SPARQL matches anything else. The catalogue is in the named graph `urn:sophia:garden:uruguay-catalogue:dcat` (always wrap patterns in `GRAPH`): ```sparql PREFIX dcat: PREFIX dct: SELECT ?dataset ?title WHERE { GRAPH { ?dataset a dcat:Dataset ; dct:title ?title ; dct:publisher . } } ORDER BY ?title ``` #### From a dataset to its files ```sparql PREFIX dcat: PREFIX dct: SELECT ?file ?format ?url ?modified WHERE { GRAPH { dcat:distribution ?d . ?d dct:title ?file ; dct:format ?format ; dcat:accessURL ?url . OPTIONAL { ?d dct:modified ?modified } } } ``` `dcat:downloadURL` is set when the file is an upload or a file format (CSV, XLSX, JSON, ZIP, SHP and the like); a link to an API or a web page has only `dcat:accessURL`. The files themselves are not in the graph: fetch them from the publisher's URL. #### What else is recorded - **Themes:** the catalogue's 22 groups (`dcat:theme`, SKOS concepts with Spanish and English labels): Statistics, Transparency, Education, Health, Agriculture and so on. - **Licences:** 2,664 datasets carry the Licencia de Datos Abiertos – Uruguay; the rest CC0, CC BY, CC BY-SA, one CC BY-NC, and 24 no licence stated (`dct:license`). - **Frequency:** the catalogue's update frequency in days (`uycat:updateFrequencyDays`), and the EU frequency term where the number has an obvious one. - **Provenance:** the named graph `urn:sophia:garden:uruguay-catalogue:provenance` records the harvest (date, requests, the sha256 of every raw answer) and the attribution the licence asks for. #### Citing what you find The licence asks anyone who uses the data or the metadata to name the provider, the "Licencia de Datos Abiertos – Uruguay", and the dataset, and to say what they changed. For the catalogue itself: *Fuente: Catálogo Nacional de Datos Abiertos (catalogodatos.gub.uy), metadatos de cada organismo proveedor, Licencia de Datos Abiertos – Uruguay; cosechados el 14/10/2026 y convertidos a DCAT por Sophia Labs, con glosas en inglés no oficiales.* For a dataset: its publisher, its title and its catalogue address. The catalogue changes; this graph does not, until the next harvest. The date on the cards is the date of the world they describe. --- *This guide is by Sophia Labs, under CC BY 4.0. The data it describes is MGAP's (and, for the catalogue, each publisher's), under the Licencia de Datos Abiertos – Uruguay.* The cow-tools guide, The guide: https://cow-tools.sophia-labs.com/guide/finding-other-uruguay-data/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `finding-other-uruguay-data` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/finding-other-uruguay-data/index.md · page: https://cow-tools.sophia-labs.com/guide/finding-other-uruguay-data/) --- ### Questions with exact answers Each question below was asked through the MCP endpoint, of the curated tools, and each answer was checked against a sum computed directly from MGAP's CSV files by a separate program that shares no code with the tools. They agreed to the animal. If a tool ever disagrees with these numbers for the same year, believe neither, and tell us. #### How many dairy cows were there in Florida in 2025? **100,116** by MGAP's dairy measure (PD+PF: 79,048 milking cows and 21,068 dry cows), or **103,472** by DICOSE's traditional count (PD+AD). Florida is department 7; dairy cattle are species 11; milking and dry cows are its categories 2 and 3. ``` cow_herd species: "dairy cattle" department: "Florida" categories: ["2", "3"] year: 2025 ``` The answer names its source rows (`datosanimalesdetallados.csv`), both measures, and which one MGAP uses for dairy. The two differ because some cows graze on other people's land; see *Known caveats*. #### How many cattle did Uruguay have? **12,265,269** in 2025 and **12,138,148** in 2024 (beef and dairy cattle together, PD+AD): up 127,121. In 2025, 11,583,321 were beef cattle and 681,948 dairy cattle. ``` cow_rank metric: "bovine_count" year: 2025 limit: 19 (sum the 19 departments) ``` #### Which department has the most cattle? **Florida**, with 1,117,097 in 2025 (1,095,226 in 2024). Then Tacuarembó (1,061,136) and Durazno (952,171). In 2024 the third was Cerro Largo. ``` cow_rank metric: "bovine_count" year: 2025 limit: 3 ``` #### How many cattle are there in Montevideo? **2,736** in 2025 (2,699 in 2024). Montevideo is the capital and the smallest department, and it is not empty of cows. ``` cow_area_profile department: "Montevideo" year: 2025 ``` #### How many sheep? **4,799,066** in 2025, down from **5,420,661** in 2024: 621,595 fewer, a fall of 11.5% in one year. ``` cow_rank metric: "ovine_count" year: 2025 limit: 19 (sum the 19 departments) cow_compare years: [2024, 2025] metrics: ["ovine_count"] ``` #### Where is the milk? **Florida** again: 608,116,907 litres declared for 2025, of 2,298,402,318 nationally. Then San José (520,036,099) and Colonia (441,387,725). ``` cow_rank metric: "milk_liters" year: 2025 limit: 3 ``` #### Questions the tools refuse - *How many cows in 2019?* Refused: the loaded years are 2024 and 2025. - *How many cows in "Floridaa"?* Refused, with the list of the 19 departments. - *Rank departments with `filters: {department: "7"}`?* Refused: `cow_rank` takes no `filters`, and a filter silently ignored would be a wrong answer that looks right. - *A SPARQL query that joins every observation to every other?* Stopped at its deadline (10 seconds on the public endpoint, at most 1,000 rows), and the answer says it was stopped. The curated tools have a budget of their own (20 seconds) and say the same when they run out of it. --- *This guide is by Sophia Labs, under CC BY 4.0. The data it describes is MGAP's, under the Licencia de Datos Abiertos – Uruguay.* The cow-tools guide, The guide: https://cow-tools.sophia-labs.com/guide/questions-with-exact-answers/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `questions-with-exact-answers` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/questions-with-exact-answers/index.md · page: https://cow-tools.sophia-labs.com/guide/questions-with-exact-answers/) --- ### Glossary: DICOSE and the cube **The words you need to read Uruguay's livestock declarations, and how cow-tools models them.** #### The institutions - **MGAP**: Ministerio de Ganadería, Agricultura y Pesca, Uruguay's ministry of livestock, agriculture and fisheries. - **DICOSE**: División de Contralor de Semovientes, the MGAP division that registers every livestock holder. Each year every holder files a **declaración jurada** (sworn declaration) of the animals on the holding on 30 June. - **SNIG**: Sistema Nacional de Información Ganadera, the national livestock information system that publishes the aggregates. - **DIEA**: MGAP's statistics directorate; it drew the census areas. - **catalogodatos.gub.uy**: the national open-data catalogue (CKAN) where SNIG publishes one package per year. #### The geography - **Departamento**: one of Uruguay's 19 first-level divisions. DICOSE codes them 1–19 alphabetically (1 Artigas … 19 Treinta y Tres); in the cube they are `urn:sophia:cow:department/`. - **Área de enumeración**: a DIEA census area, the finest grain published (635 codes). A holding is placed in the area holding most of its declared land; code `0` means it could not be placed. An area can straddle a department line, because the department is where the holder is registered. - **Seccional policial** and **área de supervisión**: older administrative grids also carried on every row. #### The counts - **PD_AD** (*propios dentro + ajenos dentro*): animals physically on the holding, whoever owns them. The traditional DICOSE stock; the cube's `cow:animalsCount`. - **PD_PF** (*propios dentro + propios fuera*): the holder's own animals, here or elsewhere. DICOSE uses it for dairy; the cube's `cow:animalsCountPf`. - **Nacimientos, mortandad, consumo**: calves born, deaths and animals slaughtered for the holding's own consumption during the year. Births are declared only for cattle. - **Tenedores**: holders, the people or companies that declare. - **Superficie ganadera**: hectares a holder uses for livestock (`cow:livestockHectares`). - **Unidades ganaderas (UG)**: livestock units, a grazing-equivalent weight per category (below). #### The land - **Campo natural**: native grassland (and stubble), most of Uruguay. - **Praderas artificiales permanentes**: sown permanent pasture. - **Campo mejorado / fertilizado**: native grassland improved by overseeding or fertiliser. #### The trade - **Cría**: breeding; keeping cows and selling calves. **Invernada**: finishing; buying young cattle and fattening them. **Ciclo completo**: both. - **Offtake / extraction rate**: cattle that left the farms in a year (to slaughter, live export, or another region), inferred from the herd's books; as a share of opening stock. #### Species and categories | code | species | | --- | --- | | 1 | BOVINOS | | 2 | OVINOS | | 3 | YEGUARIZOS | | 4 | CAPRINOS | | 5 | SUINOS | | 10 | AVES | | 11 | BOVINOS DE LECHE | Category codes are only unique *within* a species: code 2 is a breeding cow for beef cattle, a breeding ewe for sheep and a milking cow for dairy cattle. The cube's category IRIs carry the species (`urn:sophia:cow:animal-category//`). **Beef cattle (BOVINOS)**, species code `1`: | code | DICOSE label | livestock-unit weight | | --- | --- | --- | | 1 | 1) TOROS | 1,25 | | 2 | 2) VACAS DE CRIA (ENTORADAS) | 1,03 | | 3 | 3) VACAS DE INVERNADA | 1,00 | | 4 | 4) NOVILLOS DE MAS DE 3 AÑOS | 1,15 | | 5 | 5) NOVILLOS DE 2 A 3 AÑOS | 0,90 | | 6 | 6) NOVILLOS DE 1 A 2 AÑOS | 0,80 | | 7 | 7) VAQUILLONA DE MAS DE 2 AÑOS SIN ENTORAR | 0,90 | | 8 | 8) VAQUILLONAS DE 1 A 2 AÑOS | 0,70 | | 9 | 9) TERNEROS/TERNERAS | 0,50 | **Dairy cattle (BOVINOS DE LECHE)**, species code `11`: | code | DICOSE label | livestock-unit weight | | --- | --- | --- | | 1 | 1) TOROS | 0,55 | | 2 | 2) VACAS EN ORDEÑE | 0,58 | | 3 | 3) VACAS SECAS | 0,18 | | 4 | 4) VAQUILLONAS DE MÁS DE 2 AÑOS SIN ENTORAR | 0,00 | | 5 | 5) VAQUILLONAS DE 1 Ó 2 AÑOS | 0,00 | | 6 | 6) TERNEROS DE MENOS DE 1 AÑO | -0,10 | | 7 | 7) TERNERAS DE MENOS DE 1 AÑO | -0,10 | **Sheep (OVINOS)**, species code `2`: | code | DICOSE label | livestock-unit weight | | --- | --- | --- | | 1 | 1) CARNEROS | 0,17 | | 2 | 2) OVEJAS DE CRIA(ENCARNERADAS) | 0,17 | | 3 | 3) OVEJAS DE DESCARTE(CONSUMO) | 0,15 | | 4 | 4) CAPONES | 0,15 | | 5 | 5) BORREGAS 2 A 4 DIENTES SIN ENCARNERAR | 0,13 | | 6 | 6) CORDERAS DIENTE DE LECHE | 0,11 | | 7 | 7) CORDEROS DIENTE DE LECHE | 0,11 | | 8 | 8) CORDEROS/AS MAMONES | 0,08 | #### The cube - **RDF Data Cube** (`qb:`): each CSV row is an observation with dimensions (year, department, census area, species, category …) and measures (`cow:animalsCount`, `cow:milkLiters`, `cow:hectares` …). Classes: `cow:AnimalFlowObservation`, `cow:AnimalCategoryStockObservation`, `cow:GeneralHoldingObservation`, `cow:LandUseObservation`, `cow:MilkProductionObservation` and others. - **PROV**: every observation names its source file (`cow:sourceFile`, with filename and SHA-256) and row (`cow:sourceRowNumber`). - **Named graphs**: observations, codelists, derived metrics and quality reports live in separate named graphs per year, so every SPARQL pattern must sit inside `GRAPH ?g { … }`. - **Derived metrics** (`cow:DerivedMetricObservation`): ratios and shares cow-tools materialises at ingest, e.g. `cow:metric_bovine_per_livestock_hectare`. - **Quality warnings** (`cow:QualityWarning`): what the ingest noticed, per year; read them before comparing years. See also: [`how-to-ask-this-data`](https://cow-tools.sophia-labs.com/guide/how-to-ask-this-data/index.md), [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Reference: https://cow-tools.sophia-labs.com/guide/glossary-dicose/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `glossary-dicose` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/glossary-dicose/index.md · page: https://cow-tools.sophia-labs.com/guide/glossary-dicose/) --- ### How to ask this data a question **Connect any MCP client to `https://cow-tools.sophia-labs.com/mcp` (no account), or POST SPARQL to `https://cow-tools.sophia-labs.com/api/sparql/query` with `{"graphId": "uruguay-cows", "query": …}`. Wrap every pattern in `GRAPH ?g { … }`. An empty answer means the question was asked wrong, not that the answer is zero.** #### Three ways in 1. **An agent, over MCP.** Point Claude, ChatGPT or any MCP client at the endpoint: ```json { "mcpServers": { "cow-tools": { "url": "https://cow-tools.sophia-labs.com/mcp" } } } ``` The curated tools answer common questions with provenance attached (`cow_area_profile`, `cow_compare`, `cow_export_table`, `cow_geo_sources`, `cow_herd`, `cow_map`, `cow_metric`, `cow_quality_report`, `cow_rank`, `cow_report`, `cow_reports`, `cow_schema`, `cow_sidecar_status`, `cow_sources`); the graph tools (`sparql_query`, `semantic_search`, `read_document`, `search_documents` …) reach everything else. 1. **SPARQL over HTTP**, from anything that can POST JSON: ```sh curl -s https://cow-tools.sophia-labs.com/api/sparql/query -H 'Content-Type: application/json' \ -d '{"graphId":"uruguay-cows","query":"PREFIX cow: SELECT (COUNT(*) AS ?n) WHERE { GRAPH ?g { ?o a cow:MilkProductionObservation } }"}' ``` 1. **Python**, with the notebooks' helper (`cowtools_client.py`, in the notebooks zip): ```python import cowtools_client as cw cw.sparql('SELECT ... WHERE { GRAPH ?g { ... } }') # a DataFrame cw.tool('cow_rank', metric='bovine_count', entity='department', year=2025) ``` #### Examples, run when this page was built Each query below was executed against the endpoint as this document was written; the answer shown is what it returned. ```sparql PREFIX cow: PREFIX qb: PREFIX prov: PREFIX skos: PREFIX dct: PREFIX dcat: PREFIX rdfs: PREFIX xsd: ``` ##### How many cattle did Uruguay declare in 2025? ```sparql SELECT (SUM(?n) AS ?cattle) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year "2025"^^xsd:gYear ; cow:species ?s ; cow:animalsCount ?n . VALUES ?s { } } } ``` | cattle | | --- | | 12,265,269 | ##### Which five departments have the most sheep? ```sparql SELECT ?department (SUM(?n) AS ?sheep) WHERE { GRAPH ?g { ?obs a cow:AnimalFlowObservation ; cow:year "2025"^^xsd:gYear ; cow:species ; cow:department ?department ; cow:animalsCount ?n . } } GROUP BY ?department ORDER BY DESC(?sheep) LIMIT 5 ``` | department | sheep | | --- | --- | | urn:sophia:cow:department/15 | 1,032,181 | | urn:sophia:cow:department/1 | 801,403 | | urn:sophia:cow:department/11 | 555,079 | | urn:sophia:cow:department/18 | 398,742 | | urn:sophia:cow:department/3 | 303,495 | ##### Where did a number come from? (the source file and row of one observation) ```sparql SELECT ?obs ?file ?filename ?sha256 ?row WHERE { GRAPH ?g { ?obs a cow:MilkProductionObservation ; cow:year "2025"^^xsd:gYear ; cow:department ; cow:sourceFile ?file ; cow:sourceRowNumber ?row . } GRAPH ?s { ?file cow:filename ?filename ; cow:sha256 ?sha256 } } ORDER BY ?row LIMIT 1 ``` | obs | file | filename | sha256 | row | | --- | --- | --- | --- | --- | | urn:sophia:cow:obs/2025/produccion-leche/a39876896a157117 | urn:sophia:cow:file/2025/produccionleche-csv/3645c711b69c | produccionleche.csv | 3645c711b69cbd8669e204caf421791ee7fae1c052ca72bc92cf79eed4b978c4 | 1,889 | #### The rules of the house - **Wrap patterns in `GRAPH ?g { … }`.** The cube lives in named graphs (observations, codelists, derived metrics and quality, per year). An unwrapped pattern matches nothing. - **Filter years with the literal** `cow:year "2025"^^xsd:gYear`. - **Cattle are two species**: beef `1` and dairy `11`. Sheep are `2`. - **Stock is PD_AD** (`cow:animalsCount`) unless you mean the holder's own animals (`cow:animalsCountPf`, the dairy convention). - **Read the year's quality warnings** (`cow:QualityWarning`) before comparing years. - **Fail loudly.** If a number looks wrong, it probably is: check it against the source file named in its provenance (`cow:sourceFile`, with its SHA-256). #### Talking to an agent The demo also hosts a personal agent over the data (the ride protocol). Reading and the tools are free; a conversation needs your own OpenRouter key (sent per request as `X-Model-Key`, kept in memory for the session) or a Sophia account. See the notebook [*Ask the agent*](https://cow-tools.sophia-labs.com/guide/notebook-ask-the-agent/index.md). See also: [`glossary-dicose`](https://cow-tools.sophia-labs.com/guide/glossary-dicose/index.md), [`reading-path`](https://cow-tools.sophia-labs.com/guide/reading-path/index.md). --- This document is CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), credit "cow-tools, Sophia Labs"; the data it describes keeps its own licence (Uruguay's open-data licence). The cow-tools guide, Reference: https://cow-tools.sophia-labs.com/guide/how-to-ask-this-data/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `cow-tools-guide`, document `how-to-ask-this-data` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/how-to-ask-this-data/index.md · page: https://cow-tools.sophia-labs.com/guide/how-to-ask-this-data/) --- ### Moo-vements of the Spirit Signed-in visitors will be able to write here soon. A folder of the cow-tools guide (graph `cow-tools-guide`, folder `moo-vements-of-the-spirit`). The guide: https://cow-tools.sophia-labs.com/guide/index.md (Markdown: https://cow-tools.sophia-labs.com/guide/moo-vements-of-the-spirit/index.md · page: https://cow-tools.sophia-labs.com/guide/moo-vements-of-the-spirit/) --- ### About this graph `uruguay-cows` is Uruguay's sworn livestock declarations (DICOSE, MGAP/SNIG) for 2024 and 2025, as RDF: every published row an observation in a Data Cube, every observation traceable to its file, every file to its download on the national catalogue. About twenty-five million quads, for some twelve million cattle, nearly five million sheep, a few hundred thousand horses and a declared number of goats. Two ways in: - the curated `cow_*` tools (`cow_herd`, `cow_rank`, `cow_area_profile`, `cow_compare`, `cow_quality_report`, …), listed beside Sophia's own tools on the same MCP endpoint; they name departments and species in plain words and refuse what they cannot answer; - SPARQL (`sparql_query`), over the named graphs `urn:sophia:garden:uruguay-cows:cow:*`; wrap every pattern in `GRAPH`. The guide graph `cow-tools-guide` explains what DICOSE is, how to read the cubes, the caveats, and how to find the rest of Uruguay's data, and keeps a list of questions with exact answers. Source: MGAP – SNIG, *Declaración Jurada de Existencias DICOSE* 2024 and 2025 (catalogodatos.gub.uy), Licencia de Datos Abiertos – Uruguay. Converted to RDF by Sophia Labs (cow-tools); the derived metrics are cow-tools' arithmetic, not MGAP's. The cow-tools guide, About the data: https://cow-tools.sophia-labs.com/guide/about-uruguay-cows/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `uruguay-cows`, document `about-uruguay-cows` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/about-uruguay-cows/index.md · page: https://cow-tools.sophia-labs.com/guide/about-uruguay-cows/) --- ### About this graph `uruguay-catalogue` is every dataset on Uruguay's national open-data catalogue (catalogodatos.gub.uy) as it stood on 14 October 2026: 2,718 datasets, 14,426 files, 70 publishers, 22 themes, as DCAT in the named graph `urn:sophia:garden:uruguay-catalogue:dcat`, with the harvest's provenance in `urn:sophia:garden:uruguay-catalogue:provenance`. The folder *Every dataset, by publisher* holds one card per publisher and one paragraph per dataset, which is what semantic search reads: ask in Spanish or English ("consumo de energía", "school enrolment") and the paragraphs that answer come back, each ending with the dataset's IRI. From the IRI, SPARQL gives the files and their download links (`dcat:distribution`, `dcat:downloadURL`). The English after each title is Sophia's gloss, not the publisher's. The metadata belongs to its publishers, under the Licencia de Datos Abiertos – Uruguay (or the licence each dataset names): *Fuente: Catálogo Nacional de Datos Abiertos (catalogodatos.gub.uy), metadatos de cada organismo proveedor; cosechados el 14/10/2026 y convertidos a DCAT por Sophia Labs, con glosas en inglés no oficiales; se omitieron los correos de contacto.* How to search it, and what it does not contain, is in the guide graph `cow-tools-guide` under *Finding other Uruguay data*. The cow-tools guide, About the data: https://cow-tools.sophia-labs.com/guide/about-uruguay-catalogue/ (this page for people) · the whole guide: https://cow-tools.sophia-labs.com/guide/index.md · in Sophia: the graph `uruguay-catalogue`, document `about-uruguay-catalogue` (MCP `read_document` at https://cow-tools.sophia-labs.com/mcp). CC BY 4.0, credit "cow-tools, Sophia Labs". (Markdown: https://cow-tools.sophia-labs.com/guide/about-uruguay-catalogue/index.md · page: https://cow-tools.sophia-labs.com/guide/about-uruguay-catalogue/)