{"id":346358,"name":"pysheds","description":"Simple and fast watershed delineation in Python.","url":"https://github.com/pysheds/pysheds","last_synced_at":"2026-04-07T01:00:29.072Z","repository":{"id":43669620,"uuid":"88182854","full_name":"pysheds/pysheds","owner":"pysheds","description":"Simple and fast watershed delineation in python","archived":false,"fork":false,"pushed_at":"2026-04-01T13:48:48.000Z","size":15207,"stargazers_count":876,"open_issues_count":65,"forks_count":228,"subscribers_count":28,"default_branch":"master","last_synced_at":"2026-04-04T01:02:26.000Z","etag":null,"topics":["accumulation","catchments","digital-elevation-model","flow-direction","gis","hydrology"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pysheds.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-04-13T16:02:37.000Z","updated_at":"2026-04-02T12:58:47.000Z","dependencies_parsed_at":"2023-12-11T22:03:43.849Z","dependency_job_id":"474bbc6e-d11e-4f97-97b5-1ba758048b72","html_url":"https://github.com/pysheds/pysheds","commit_stats":{"total_commits":416,"total_committers":11,"mean_commits":37.81818181818182,"dds":"0.14903846153846156","last_synced_commit":"4030e60e1555b7b639de1ce2eeda50a7df919fd5"},"previous_names":["pysheds/pysheds","mdbartos/pysheds"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/pysheds/pysheds","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pysheds","download_url":"https://codeload.github.com/pysheds/pysheds/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31495466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"owner":{"login":"pysheds","name":"pysheds","uuid":"218899350","kind":"organization","description":null,"email":null,"website":null,"location":null,"twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/218899350?v=4","repositories_count":1,"last_synced_at":"2026-03-06T05:37:33.860Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/pysheds","funding_links":[],"total_stars":860,"followers":0,"following":0,"created_at":"2026-03-06T05:37:33.881Z","updated_at":"2026-03-06T05:37:33.881Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pysheds","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pysheds/repositories"},"packages":[],"commits":{"id":11690822,"full_name":"pysheds/pysheds","default_branch":"master","total_commits":429,"total_committers":13,"total_bot_commits":3,"total_bot_committers":1,"mean_commits":33.0,"dds":0.1631701631701632,"past_year_total_commits":12,"past_year_total_committers":6,"past_year_total_bot_commits":3,"past_year_total_bot_committers":1,"past_year_mean_commits":2.0,"past_year_dds":0.5833333333333333,"last_synced_at":"2026-04-04T01:01:13.942Z","last_synced_commit":"ad2204b7ba24cd49ffa0827a3c6dbbc82af26010","created_at":"2026-03-22T01:00:20.363Z","updated_at":"2026-04-04T01:00:49.905Z","committers":[{"name":"Matt Bartos","email":"mdbartos@umich.edu","login":"mdbartos","count":359},{"name":"Zeitsperre","email":"10819524+Zeitsperre","login":"Zeitsperre","count":17},{"name":"Ryan Grout","email":"ryan@ryangrout.org","login":"groutr","count":14},{"name":"itati01","email":"itati01","login":"itati01","count":13},{"name":"rickD","email":"debboutr@gmail.com","login":"debboutr","count":8},{"name":"Philipp Kraft","email":"philipp.kraft@umwelt.uni-giessen.de","login":null,"count":4},{"name":"dependabot[bot]","email":"49699333+dependabot[bot]","login":"dependabot[bot]","count":3},{"name":"Philipp Kraft","email":"oekopez@gmx.de","login":"philippkraft","count":3},{"name":"Jonathan King","email":"jonking93@gmail.com","login":"JonKing93","count":3},{"name":"Matthew Plough","email":"matt.plough@koboldmetals.com","login":"mplough-kobold","count":2},{"name":"Thomas Grandjean","email":"tgrandje@gmail.com","login":"tgrandje","count":1},{"name":"Juan David","email":"77643820+JuanGuerrero09","login":"JuanGuerrero09","count":1},{"name":"David Huard","email":"david.huard@gmail.com","login":"huard","count":1}],"past_year_committers":[{"name":"Matt Bartos","email":"mdbartos@utexas.edu","login":"mdbartos","count":5},{"name":"dependabot[bot]","email":"49699333+dependabot[bot]","login":"dependabot[bot]","count":3},{"name":"Trevor James Smith","email":"10819524+Zeitsperre","login":"Zeitsperre","count":1},{"name":"Thomas Grandjean","email":"tgrandje@gmail.com","login":"tgrandje","count":1},{"name":"Juan David","email":"77643820+JuanGuerrero09","login":"JuanGuerrero09","count":1},{"name":"Jonathan King","email":"jonking93@gmail.com","login":"JonKing93","count":1}],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-07T00:00:11.408Z","repositories_count":6211369,"commits_count":920250417,"contributors_count":35657621,"owners_count":1142966,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"pysheds/pysheds","html_url":"https://github.com/pysheds/pysheds","last_synced_at":"2026-04-04T01:00:29.933Z","status":"active","issues_count":4,"pull_requests_count":5,"avg_time_to_close_issue":1740207.0,"avg_time_to_close_pull_request":229662.5,"issues_closed_count":1,"pull_requests_closed_count":4,"pull_request_authors_count":3,"issue_authors_count":3,"avg_comments_per_issue":2.0,"avg_comments_per_pull_request":1.4,"merged_pull_requests_count":4,"bot_issues_count":0,"bot_pull_requests_count":3,"past_year_issues_count":4,"past_year_pull_requests_count":5,"past_year_avg_time_to_close_issue":1740207.0,"past_year_avg_time_to_close_pull_request":229662.5,"past_year_issues_closed_count":1,"past_year_pull_requests_closed_count":4,"past_year_pull_request_authors_count":3,"past_year_issue_authors_count":3,"past_year_avg_comments_per_issue":2.0,"past_year_avg_comments_per_pull_request":1.4,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":3,"past_year_merged_pull_requests_count":4,"created_at":"2026-02-26T11:00:09.551Z","updated_at":"2026-04-04T01:00:29.933Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/pysheds%2Fpysheds/issues","issue_labels_count":{"question":1},"pull_request_labels_count":{"dependencies":3,"python":2,"github_actions":1,"enhancement":1},"issue_author_associations_count":{"CONTRIBUTOR":3,"NONE":1},"pull_request_author_associations_count":{"CONTRIBUTOR":4,"NONE":1},"issue_authors":{"Zeitsperre":2,"JonKing93":1,"mvhulten":1},"pull_request_authors":{"dependabot[bot]":3,"jameshgrn":1,"Zeitsperre":1},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-07T00:00:09.463Z","repositories_count":14116540,"issues_count":34490057,"pull_requests_count":112629823,"authors_count":11228003,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{"question":1},"past_year_pull_request_labels_count":{"dependencies":3,"python":2,"enhancement":1,"github_actions":1},"past_year_issue_author_associations_count":{"CONTRIBUTOR":3,"NONE":1},"past_year_pull_request_author_associations_count":{"CONTRIBUTOR":4,"NONE":1},"past_year_issue_authors":{"Zeitsperre":2,"JonKing93":1,"mvhulten":1},"past_year_pull_request_authors":{"dependabot[bot]":3,"jameshgrn":1,"Zeitsperre":1},"maintainers":[],"active_maintainers":[]},"events":{"total":{"DeleteEvent":2,"MemberEvent":1,"DiscussionEvent":1,"IssuesEvent":4,"WatchEvent":3,"IssueCommentEvent":5,"PushEvent":4,"PullRequestReviewEvent":6,"CreateEvent":1},"last_year":{"DeleteEvent":2,"MemberEvent":1,"DiscussionEvent":1,"IssuesEvent":4,"WatchEvent":3,"IssueCommentEvent":5,"PushEvent":4,"PullRequestReviewEvent":6,"CreateEvent":1}},"keywords":["accumulation","catchments","digital-elevation-model","flow-direction","gis","hydrology"],"dependencies":[{"ecosystem":"pypi","filepath":"setup.py","sha":null,"kind":"manifest","created_at":"2022-08-12T10:42:01.935Z","updated_at":"2022-08-12T10:42:01.935Z","repository_link":"https://github.com/pysheds/pysheds/blob/master/setup.py","dependencies":[{"id":1316539378,"package_name":"numpy","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539383,"package_name":"numba","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539385,"package_name":"pandas","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539386,"package_name":"scipy","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539388,"package_name":"pyproj","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539389,"package_name":"scikit-image","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539391,"package_name":"affine","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539392,"package_name":"geojson","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":1316539393,"package_name":"rasterio","ecosystem":"pypi","requirements":"\u003e=1","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/python-package.yml","sha":null,"kind":"manifest","created_at":"2023-01-23T01:45:55.823Z","updated_at":"2023-01-23T01:45:55.823Z","repository_link":"https://github.com/pysheds/pysheds/blob/master/.github/workflows/python-package.yml","dependencies":[{"id":7106595424,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":7106595426,"package_name":"actions/setup-python","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/python-publish.yml","sha":null,"kind":"manifest","created_at":"2023-01-23T01:45:55.868Z","updated_at":"2023-01-23T01:45:55.868Z","repository_link":"https://github.com/pysheds/pysheds/blob/master/.github/workflows/python-publish.yml","dependencies":[{"id":7106595834,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":7106595835,"package_name":"actions/setup-python","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":7106595836,"package_name":"pypa/gh-action-pypi-publish","ecosystem":"actions","requirements":"27b31702a0e7fc50959f5ad993c78deac1bdfc29","direct":true,"kind":"composite","optional":false}]}],"score":9.411892497046916,"created_at":"2026-02-24T00:24:12.316Z","updated_at":"2026-04-07T01:00:29.084Z","avatar_url":"https://github.com/pysheds.png","language":"Python","category":"Natural Resources","sub_category":"Water Supply and Quality","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"# pysheds [![Build Status](https://github.com/mdbartos/pysheds/actions/workflows/python-package.yml/badge.svg)](https://github.com/mdbartos/pysheds/actions) [![Coverage Status](https://coveralls.io/repos/github/mdbartos/pysheds/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/mdbartos/pysheds?branch=master) [![Python Versions](https://img.shields.io/pypi/pyversions/pysheds)](https://pypi.python.org/pypi/pysheds)\n🌎 Simple and fast watershed delineation in python.\n\n## Documentation\n\nRead the docs [here 📖](https://mdbartos.github.io/pysheds).\n\n## Media\n\n*Hatari Labs* - [Elevation model conditioning and stream network delineation with python and pysheds](https://www.hatarilabs.com/ih-en/elevation-model-conditioning-and-stream-network-delimitation-with-python-and-pysheds-tutorial) \u003csup\u003e:uk:\u003c/sup\u003e\n\n*Hatari Labs* - [Watershed and stream network delineation with python and pysheds](https://www.hatarilabs.com/ih-en/watershed-and-stream-network-delimitation-with-python-and-pysheds-tutorial) \u003csup\u003e:uk:\u003c/sup\u003e\n\n*Gidahatari* - [Delimitación de límite de cuenca y red hidrica con python y pysheds](http://gidahatari.com/ih-es/delimitacion-de-limite-de-cuenca-y-red-hidrica-con-python-y-pysheds-tutorial) \u003csup\u003e:es:\u003c/sup\u003e\n\n*Earth Science Information Partners* - [Pysheds: a fast, open-source digital elevation model processing library](https://www.esipfed.org/student-fellow-blog/pysheds-a-fast-open-source-digital-elevation-model-processing-library) \u003csup\u003e:uk:\u003c/sup\u003e\n\n## Example usage\n\nExample data used in this tutorial are linked below:\n\n  - Elevation: [elevation.tiff](https://pysheds.s3.us-east-2.amazonaws.com/data/elevation.tiff)\n  - Terrain: [impervious_area.zip](https://pysheds.s3.us-east-2.amazonaws.com/data/impervious_area.zip)\n  - Soil Polygons: [soils.zip](https://pysheds.s3.us-east-2.amazonaws.com/data/soils.zip)\n  \nAdditional DEM datasets are available via the [USGS HydroSHEDS](https://www.hydrosheds.org/) project.\n\n### Read DEM data\n\n```python\n# Read elevation raster\n# ----------------------------\nfrom pysheds.grid import Grid\n\ngrid = Grid.from_raster('elevation.tiff')\ndem = grid.read_raster('elevation.tiff')\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib import colors\nimport seaborn as sns\n\nfig, ax = plt.subplots(figsize=(8,6))\nfig.patch.set_alpha(0)\n\nplt.imshow(dem, extent=grid.extent, cmap='terrain', zorder=1)\nplt.colorbar(label='Elevation (m)')\nplt.grid(zorder=0)\nplt.title('Digital elevation map', size=14)\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nplt.tight_layout()\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 1](https://pysheds.s3.us-east-2.amazonaws.com/img/dem.png)\n\n### Condition the elevation data\n\n```python\n# Condition DEM\n# ----------------------\n# Fill pits in DEM\npit_filled_dem = grid.fill_pits(dem)\n\n# Fill depressions in DEM\nflooded_dem = grid.fill_depressions(pit_filled_dem)\n    \n# Resolve flats in DEM\ninflated_dem = grid.resolve_flats(flooded_dem)\n```\n\n### Elevation to flow direction\n\n```python\n# Determine D8 flow directions from DEM\n# ----------------------\n# Specify directional mapping\ndirmap = (64, 128, 1, 2, 4, 8, 16, 32)\n    \n# Compute flow directions\n# -------------------------------------\nfdir = grid.flowdir(inflated_dem, dirmap=dirmap)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nfig = plt.figure(figsize=(8,6))\nfig.patch.set_alpha(0)\n\nplt.imshow(fdir, extent=grid.extent, cmap='viridis', zorder=2)\nboundaries = ([0] + sorted(list(dirmap)))\nplt.colorbar(boundaries= boundaries,\n             values=sorted(dirmap))\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nplt.title('Flow direction grid', size=14)\nplt.grid(zorder=-1)\nplt.tight_layout()\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 2](https://pysheds.s3.us-east-2.amazonaws.com/img/fdir.png)\n\n### Compute accumulation from flow direction\n\n```python\n# Calculate flow accumulation\n# --------------------------\nacc = grid.accumulation(fdir, dirmap=dirmap)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nfig, ax = plt.subplots(figsize=(8,6))\nfig.patch.set_alpha(0)\nplt.grid('on', zorder=0)\nim = ax.imshow(acc, extent=grid.extent, zorder=2,\n               cmap='cubehelix',\n               norm=colors.LogNorm(1, acc.max()),\n               interpolation='bilinear')\nplt.colorbar(im, ax=ax, label='Upstream Cells')\nplt.title('Flow Accumulation', size=14)\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nplt.tight_layout()\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 4](https://pysheds.s3.us-east-2.amazonaws.com/img/acc.png)\n\n\n### Delineate catchment from flow direction\n\n```python\n# Delineate a catchment\n# ---------------------\n# Specify pour point\nx, y = -97.294, 32.737\n\n# Snap pour point to high accumulation cell\nx_snap, y_snap = grid.snap_to_mask(acc \u003e 1000, (x, y))\n\n# Delineate the catchment\ncatch = grid.catchment(x=x_snap, y=y_snap, fdir=fdir, dirmap=dirmap, \n                       xytype='coordinate')\n\n# Crop and plot the catchment\n# ---------------------------\n# Clip the bounding box to the catchment\ngrid.clip_to(catch)\nclipped_catch = grid.view(catch)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\n# Plot the catchment\nfig, ax = plt.subplots(figsize=(8,6))\nfig.patch.set_alpha(0)\n\nplt.grid('on', zorder=0)\nim = ax.imshow(np.where(clipped_catch, clipped_catch, np.nan), extent=grid.extent,\n               zorder=1, cmap='Greys_r')\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nplt.title('Delineated Catchment', size=14)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 3](https://pysheds.s3.us-east-2.amazonaws.com/img/catch.png)\n\n### Extract the river network\n\n```python\n# Extract river network\n# ---------------------\nbranches = grid.extract_river_network(fdir, acc \u003e 50, dirmap=dirmap)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nsns.set_palette('husl')\nfig, ax = plt.subplots(figsize=(8.5,6.5))\n\nplt.xlim(grid.bbox[0], grid.bbox[2])\nplt.ylim(grid.bbox[1], grid.bbox[3])\nax.set_aspect('equal')\n\nfor branch in branches['features']:\n    line = np.asarray(branch['geometry']['coordinates'])\n    plt.plot(line[:, 0], line[:, 1])\n    \n_ = plt.title('D8 channels', size=14)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 6](https://pysheds.s3.us-east-2.amazonaws.com/img/river.png)\n\n### Compute flow distance from flow direction\n\n```python\n# Calculate distance to outlet from each cell\n# -------------------------------------------\ndist = grid.distance_to_outlet(x=x_snap, y=y_snap, fdir=fdir, dirmap=dirmap,\n                               xytype='coordinate')\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nfig, ax = plt.subplots(figsize=(8,6))\nfig.patch.set_alpha(0)\nplt.grid('on', zorder=0)\nim = ax.imshow(dist, extent=grid.extent, zorder=2,\n               cmap='cubehelix_r')\nplt.colorbar(im, ax=ax, label='Distance to outlet (cells)')\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nplt.title('Flow Distance', size=14)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 5](https://pysheds.s3.us-east-2.amazonaws.com/img/dist.png)\n\n### Add land cover data\n\n```python\n# Combine with land cover data\n# ---------------------\nterrain = grid.read_raster('impervious_area.tiff', window=grid.bbox,\n                           window_crs=grid.crs, nodata=0)\n# Reproject data to grid's coordinate reference system\nprojected_terrain = terrain.to_crs(grid.crs)\n# View data in catchment's spatial extent\ncatchment_terrain = grid.view(projected_terrain, nodata=np.nan)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nfig, ax = plt.subplots(figsize=(8,6))\nfig.patch.set_alpha(0)\nplt.grid('on', zorder=0)\nim = ax.imshow(catchment_terrain, extent=grid.extent, zorder=2,\n               cmap='bone')\nplt.colorbar(im, ax=ax, label='Percent impervious area')\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nplt.title('Percent impervious area', size=14)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 7](https://pysheds.s3.us-east-2.amazonaws.com/img/terrain.png)\n\n### Add vector data\n\n```python\n# Convert catchment raster to vector and combine with soils shapefile\n# ---------------------\n# Read soils shapefile\nimport pandas as pd\nimport geopandas as gpd\nfrom shapely import geometry, ops\nsoils = gpd.read_file('soils.shp')\nsoil_id = 'MUKEY'\n# Convert catchment raster to vector geometry and find intersection\nshapes = grid.polygonize()\ncatchment_polygon = ops.unary_union([geometry.shape(shape)\n                                     for shape, value in shapes])\nsoils = soils[soils.intersects(catchment_polygon)]\ncatchment_soils = gpd.GeoDataFrame(soils[soil_id], \n                                   geometry=soils.intersection(catchment_polygon))\n# Convert soil types to simple integer values\nsoil_types = np.unique(catchment_soils[soil_id])\nsoil_types = pd.Series(np.arange(soil_types.size), index=soil_types)\ncatchment_soils[soil_id] = catchment_soils[soil_id].map(soil_types)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nfig, ax = plt.subplots(figsize=(8, 6))\ncatchment_soils.plot(ax=ax, column=soil_id, categorical=True, cmap='terrain',\n                     linewidth=0.5, edgecolor='k', alpha=1, aspect='equal')\nax.set_xlim(grid.bbox[0], grid.bbox[2])\nax.set_ylim(grid.bbox[1], grid.bbox[3])\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nax.set_title('Soil types (vector)', size=14)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 8](https://pysheds.s3.us-east-2.amazonaws.com/img/poly.png)\n\n### Convert from vector to raster\n\n```python\nsoil_polygons = zip(catchment_soils.geometry.values, catchment_soils[soil_id].values)\nsoil_raster = grid.rasterize(soil_polygons, fill=np.nan)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePlotting code...\u003c/summary\u003e\n\u003cp\u003e\n\n```python\nfig, ax = plt.subplots(figsize=(8, 6))\nplt.imshow(soil_raster, cmap='terrain', extent=grid.extent, zorder=1)\nboundaries = np.unique(soil_raster[~np.isnan(soil_raster)]).astype(int)\nplt.colorbar(boundaries=boundaries,\n             values=boundaries)\nax.set_xlim(grid.bbox[0], grid.bbox[2])\nax.set_ylim(grid.bbox[1], grid.bbox[3])\nplt.xlabel('Longitude')\nplt.ylabel('Latitude')\nax.set_title('Soil types (raster)', size=14)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n![Example 9](https://pysheds.s3.us-east-2.amazonaws.com/img/rasterize.png)\n\n## Features\n\n- Hydrologic Functions:\n  - `flowdir` : Generate a flow direction grid from a given digital elevation dataset.\n  - `catchment` : Delineate the watershed for a given pour point (x, y).\n  - `accumulation` : Compute the number of cells upstream of each cell; if weights are\n                given, compute the sum of weighted cells upstream of each cell.\n  - `distance_to_outlet` : Compute the (weighted) distance from each cell to a given\n                      pour point, moving downstream.\n  - `distance_to_ridge` : Compute the (weighted) distance from each cell to its originating\n                    drainage divide, moving upstream.\n  - `compute_hand` : Compute the height above nearest drainage (HAND).\n  - `stream_order` : Compute the (strahler) stream order.\n  - `extract_river_network` : Extract river segments from a catchment and return a geojson\n                        object.\n  - `extract_profiles` : Extract river segments and return a list of channel indices along with a dictionary describing connectivity.\n  - `cell_dh` : Compute the drop in elevation from each cell to its downstream neighbor.\n  - `cell_distances` : Compute the distance from each cell to its downstream neighbor.\n  - `cell_slopes` : Compute the slope between each cell and its downstream neighbor.\n  - `fill_pits` : Fill single-celled pits in a digital elevation dataset.\n  - `fill_depressions` : Fill multi-celled depressions in a digital elevation dataset.\n  - `resolve_flats` : Remove flats from a digital elevation dataset.\n  - `detect_pits` : Detect single-celled pits in a digital elevation dataset.\n  - `detect_depressions` : Detect multi-celled depressions in a digital elevation dataset.\n  - `detect_flats` : Detect flats in a digital elevation dataset.\n- Viewing Functions:\n  - `view` : Returns a \"view\" of a dataset defined by the grid's viewfinder.\n  - `clip_to` : Clip the viewfinder to the smallest area containing all non-\n          null gridcells for a provided dataset.\n  - `nearest_cell` : Returns the index (column, row) of the cell closest\n                to a given geographical coordinate (x, y).\n  - `snap_to_mask` : Snaps a set of points to the nearest nonzero cell in a boolean mask;\n                useful for finding pour points from an accumulation raster.\n- I/O Functions:\n  - `read_ascii`: Reads ascii gridded data.\n  - `read_raster`: Reads raster gridded data.\n  - `from_ascii` : Instantiates a grid from an ascii file.\n  - `from_raster` : Instantiates a grid from a raster file or Raster object.\n  - `to_ascii`: Write grids to delimited ascii files.\n  - `to_raster`: Write grids to raster files (e.g. geotiff).\n\n`pysheds` supports both D8 and D-infinity routing schemes.\n\n## Installation\n\n`pysheds` currently only supports Python 3.\n\n### Using pip\n\nYou can install `pysheds` using pip:\n\n```bash\n$ pip install pysheds\n```\n\n### Using anaconda\n\nFirst, add conda forge to your channels, if you have not already done so:\n\n```bash\n$ conda config --add channels conda-forge\n```\n\nThen, install pysheds:\n\n```bash\n$ conda install pysheds\n```\n### Installing from source\n\nFor the bleeding-edge version, you can install pysheds from this github repository.\n\n```bash\n$ git clone https://github.com/mdbartos/pysheds.git\n$ cd pysheds\n$ python setup.py install\n```\n\nor\n\n```bash\n$ git clone https://github.com/mdbartos/pysheds.git\n$ cd pysheds\n$ pip install .\n```\n\n# Performance\nPerformance benchmarks on a 2015 MacBook Pro (M: million, K: thousand):\n\n| Function                | Routing | Number of cells          | Run time |\n| ----------------------- | ------- | ------------------------ | -------- |\n| `flowdir`               | D8      |  36M                     | 1.14 [s] |\n| `flowdir`               | DINF    |  36M                     | 7.01 [s] |\n| `flowdir`               | MFD     |  36M                     | 4.21 [s] |\n| `accumulation`          | D8      |  36M                     | 3.44 [s] |\n| `accumulation`          | DINF    |  36M                     | 14.9 [s] |\n| `accumulation`          | MFD     |  36M                     | 32.5 [s] |\n| `catchment`             | D8      |  9.76M                   | 2.19 [s] |\n| `catchment`             | DINF    |  9.76M                   | 3.5  [s] |\n| `catchment`             | MFD     |  9.76M                   | 17.1 [s] |\n| `distance_to_outlet`    | D8      |  9.76M                   | 2.98 [s] |\n| `distance_to_outlet`    | DINF    |  9.76M                   | 5.49 [s] |\n| `distance_to_outlet`    | MFD     |  9.76M                   | 13.1 [s] |\n| `distance_to_ridge`     | D8      |  36M                     | 4.53 [s] |\n| `distance_to_ridge`     | DINF    |  36M                     | 14.5 [s] |\n| `distance_to_ridge`     | MFD     |  36M                     | 31.3 [s] |\n| `hand`                  | D8      |  36M total, 730K channel | 12.3 [s] |\n| `hand`                  | DINF    |  36M total, 770K channel | 15.8 [s] |\n| `hand`                  | MFD     |  36M total, 770K channel | 29.8 [s] |\n| `stream_order`          | D8      |  36M total, 1M channel   | 3.99 [s] |\n| `extract_river_network` | D8      |  36M total, 345K channel | 4.07 [s] |\n| `extract_profiles`      | D8      |  36M total, 345K channel | 2.89 [s] |\n| `detect_pits`           | N/A     |  36M                     | 1.80 [s] |\n| `detect_flats`          | N/A     |  36M                     | 1.84 [s] |\n| `fill_pits`             | N/A     |  36M                     | 2.52 [s] |\n| `fill_depressions`      | N/A     |  36M                     | 27.1 [s] |\n| `resolve_flats`         | N/A     |  36M                     | 9.56 [s] |\n| `cell_dh`               | D8      |  36M                     | 2.34 [s] |\n| `cell_dh`               | DINF    |  36M                     | 4.92 [s] |\n| `cell_dh`               | MFD     |  36M                     | 30.1 [s] |\n| `cell_distances`        | D8      |  36M                     | 1.11 [s] |\n| `cell_distances`        | DINF    |  36M                     | 2.16 [s] |\n| `cell_distances`        | MFD     |  36M                     | 26.8 [s] |\n| `cell_slopes`           | D8      |  36M                     | 4.01 [s] |\n| `cell_slopes`           | DINF    |  36M                     | 10.2 [s] |\n| `cell_slopes`           | MFD     |  36M                     | 58.7 [s] |\n\nSpeed tests were run on a conditioned DEM from the HYDROSHEDS DEM repository\n(linked above as `elevation.tiff`).\n\n# Citing\n\nIf you have used this codebase in a publication and wish to cite it, consider citing the zenodo repository:\n\n```bibtex\n@misc{bartos_2020,\n    title  = {pysheds: simple and fast watershed delineation in python},\n    author = {Bartos, Matt},\n    url    = {https://github.com/mdbartos/pysheds},\n    year   = {2020},\n    doi    = {10.5281/zenodo.3822494}\n}\n```\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":["climate","earth-system-model"],"project_url":"https://ost.ecosyste.ms/api/v1/projects/346358","html_url":"https://ost.ecosyste.ms/projects/346358"}