Searching and downloading CSDA data¶
NASA's Commercial Satellite Data Acquisition (CSDA) program acquires, catalogs, and provides commercial satellite data for the scientific community. The program's services include a SpatioTemporal Asset Catalog API server for searching and discovering CSDA assets. We'll use pystac-client to search the CSDA STAC API for items that we can use. The CSDA STAC API is public and open, meaning that we don't need any authorization or authentication to use it.
Before getting started, we import all the Python packages, classes, and functions that we need, and define a few helpful constants.
import getpass
from pathlib import Path
from tempfile import TemporaryDirectory
import contextily
import cql2
import humanize
import rasterio
import rasterio.plot
import tabulate
from geopandas import GeoDataFrame
from httpx import BasicAuth
from pystac_client import Client
from csda_client import CsdaClient
LONGMONT_CO_USA = {"type": "Point", "coordinates": [-105.1019, 40.1672]}
Collection search¶
CSDA includes data from several vendors. Each vendor maps onto a single STAC Collection, and we can use our STAC API to discover which vendors are available.
Why are there warnings?¶
The CSDA STAC catalog currently contains some invalid STAC Collections. We're working on updating those, and when we do, the warnings will go away.
stac_client = Client.open("https://csdap.earthdata.nasa.gov/stac/")
rows = []
for collection in stac_client.collection_search().collections_as_dicts():
rows.append([collection["id"], collection.get("title")])
tabulate.tabulate(rows, headers=["collection", "title"], tablefmt="html")
/Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=ghgsat warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=geooptics warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=capellaspace warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=planet warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=spire warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=airbus warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=earthdem warnings.warn( /Users/gadomski/Code/nasa-impact/csda-client/.venv/lib/python3.10/site-packages/pystac_client/collection_search.py:121: PystacClientWarning: Unable to parse extent from collection=blacksky warnings.warn(
| collection | title |
|---|---|
| ghgsat | |
| geooptics | GeoOptics |
| capellaspace | CapellaSpace |
| desis | DESIS |
| planet | Planet |
| spire | Spire |
| umbra | Umbra |
| iceye | Iceye |
| airbus | Airbus |
| earthdem | EarthDEM |
| blacksky | Blacksky |
| pgc-earthdem | EarthDEM |
Finding Planet data¶
One of the CSDA vendors, Planet, collects imagery that is easy to visualize and interpret, so let's use their data for this notebook. We can use a STAC API search query to narrow our request. In this example, we'll find STAC items that:
- are in the
planetcollection - Have a cloud cover of less than or equal to 25%
- Were collected in 2021
- Intersect Longmont, CO, USA
STAC search is extremely powerful — you can search by other attributes, control sorting, and use datetime intervals. Learn more in the pystac-client docs.
What's the deal with the cql2 stuff?¶
cql2 is an Open Geospatial Consortium standard for querying spatial data.
Our STAC API only understands cql2-json, but cql2-json can be a little awkward to write.
cql2-text is much more intuitive, so we write that and then convert it to cql2-json using this helper package.
This should become automatic via pystac-client soon.
item_search = stac_client.search(
collections=["planet"],
intersects=LONGMONT_CO_USA,
filter=cql2.parse_text("eo:cloud_cover<25").to_json(),
datetime="2021",
)
item_collection = item_search.item_collection()
print(len(item_collection))
18
Let's visualize the items, first as a GeoDataFrame.
data_frame = GeoDataFrame.from_features(item_collection.to_dict(), crs="EPSG:4326")
data_frame.head(5)
| geometry | eo:gsd | eo:epsg | pl:rows | datetime | eo:bands | eo:azimuth | pl:columns | pl:updated | pl:origin_x | ... | pl:anomalous_pixels | pl:pixel_resolution | pl:publishing_stage | pl:quality_category | pl:snow_ice_percent | pl:heavy_haze_percent | pl:light_haze_percent | pl:clear_confidence_percent | pl:visible_confidence_percent | pl:ps4b_geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | POLYGON ((-105.34272 40.22107, -105.3952 40.03... | 4.0 | 32613.0 | 9524.0 | 2021-12-30T16:54:34.641952Z | [] | 101.0 | 13191.0 | 2021-12-31T03:59:48Z | 466281.0 | ... | 0 | 3 | finalized | test | 0 | 0 | 0 | 97 | 72 | NaN |
| 1 | POLYGON ((-105.46945 40.24533, -105.5246 40.05... | 4.0 | 32613.0 | 9595.0 | 2021-12-20T17:00:46.336281Z | [] | 278.6 | 13244.0 | 2021-12-21T04:28:04Z | 455256.0 | ... | 0 | 3 | finalized | standard | 0 | 0 | 0 | 96 | 74 | NaN |
| 2 | POLYGON ((-105.49219 40.32051, -105.54659 40.1... | 4.1 | 32613.0 | 9715.0 | 2021-12-01T17:44:27.408844Z | [] | 111.8 | 13382.0 | 2021-12-02T10:03:46Z | 453429.0 | ... | 0 | 3 | finalized | standard | 0 | 0 | 0 | 97 | 59 | NaN |
| 3 | POLYGON ((-105.22817 40.32841, -105.28215 40.1... | 4.1 | NaN | NaN | 2021-11-28T16:54:46.363155Z | [] | 100.9 | NaN | 2022-10-27T11:45:48Z | NaN | ... | 0 | 3 | finalized | standard | 0 | 0 | 0 | 98 | 77 | {'type': 'Polygon', 'coordinates': [[[-105.228... |
| 4 | POLYGON ((-105.18108 40.18135, -105.23515 39.9... | 4.0 | NaN | NaN | 2021-11-25T17:11:14.321045Z | [] | 276.5 | NaN | 2022-10-30T06:51:29Z | NaN | ... | 0 | 3 | finalized | standard | 0 | 0 | 0 | 99 | 99 | NaN |
5 rows × 36 columns
Then, on a map (it's pretty noisy).
axes = data_frame.to_crs(epsg=3857).boundary.plot()
contextily.add_basemap(axes, source=contextily.providers.CartoDB.Voyager)
axes.set_axis_off()
If you happen to know your item (granule) id, you can fetch that item directly and see it's assets dictionary.
item = next(
stac_client.search(
collections=["planet"], ids=["PSScene-20250706_160525_67_24c6"]
).items()
)
item
- type "Feature"
- stac_version "1.1.0"
stac_extensions[] 1 items
- 0 "https://stac-extensions.github.io/file/v2.1.0/schema.json"
- id "PSScene-20250706_160525_67_24c6"
geometry
- type "Polygon"
coordinates[] 1 items
0[] 5 items
0[] 2 items
- 0 -71.51031041215329
- 1 44.08847606785535
1[] 2 items
- 0 -71.56277741631092
- 1 43.92181467531235
2[] 2 items
- 0 -71.17689639541125
- 1 43.85813988165753
3[] 2 items
- 0 -71.12367813028888
- 1 44.02473950851437
4[] 2 items
- 0 -71.51031041215329
- 1 44.08847606785535
bbox[] 4 items
- 0 -71.56277741631092
- 1 43.85813988165753
- 2 -71.12367813028888
- 3 44.08847606785535
properties
- eo:gsd 3.6
- datetime "2025-07-06T16:05:25.677171Z"
eo:bands[] 0 items
- eo:azimuth 111.2
- pl:updated "2025-07-07T04:02:58Z"
- pl:provider "planetscope"
- pl:strip_id "8175328"
- eo:off_nadir 1
- pl:item_type "PSScene"
- pl:published "2025-07-06T23:43:35Z"
- eo:instrument "PSB.SD"
- eo:cloud_cover 12
- eo:sun_azimuth 153.2
- pl:satellite_id "24c6"
- eo:sun_elevation 66.8
- pl:clear_percent 50
- pl:cloud_percent 12
- pl:ground_control True
- pl:shadow_percent 3
- pl:visible_percent 88
- pl:anomalous_pixels 0
- pl:pixel_resolution 3
- pl:publishing_stage "standard"
- pl:quality_category "test"
- pl:snow_ice_percent 0
- pl:heavy_haze_percent 0
- pl:light_haze_percent 35
- pl:clear_confidence_percent 84
- pl:visible_confidence_percent 77
links[] 4 items
0
- rel "collection"
- href "https://csdap.earthdata.nasa.gov/stac/collections/planet"
- type "application/json"
1
- rel "parent"
- href "https://csdap.earthdata.nasa.gov/stac/collections/planet"
- type "application/json"
2
- rel "root"
- href "https://csdap.earthdata.nasa.gov/stac/"
- type "application/json"
- title "stac-fastapi"
3
- rel "self"
- href "https://csdap.earthdata.nasa.gov/stac/collections/planet/items/PSScene-20250706_160525_67_24c6"
- type "application/geo+json"
assets
thumbnail
- href "https://ss-ingest-dev-thumbnails115905a6-1qhb7abvyj8pc.s3.amazonaws.com/planet/PSScene-20250706_160525_67_24c6/thumb"
- title "Thumbnail"
- status "active"
roles[] 1 items
- 0 "thumbnail"
basic_udm2
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/basic_udm2/20250706_160525_67_24c6_1A_udm2.tif"
- type "image/tiff"
- title "basic_udm2"
- size 5765066
- md5_digest "d75527248c9e7c830c8a931d9892a3b4"
- sha256_digest "ec574ffeea4f98f977f7153908c05e6515bd569417b1a36ea165b68583d0ab10"
- file:size 5765066
roles[] 1 items
- 0 "data"
ortho_udm2
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_udm2/20250706_160525_67_24c6_3B_udm2.tif"
- type "image/tiff"
- title "ortho_udm2"
- size 9302700
- md5_digest "4bfda8206b0939fffbdcd634abdaab4d"
- sha256_digest "fb161d5d1b857db6bd6f084eced4cc9fd0e1c048924a85fa4ec0a7126e7af952"
- file:size 9302700
roles[] 1 items
- 0 "data"
ortho_visual
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_visual/20250706_160525_67_24c6_3B_Visual.tif"
- type "image/tiff"
- title "ortho_visual"
- size 179183410
- md5_digest "92c15958bc53c8525586281147432c96"
- sha256_digest "7965668a82729982d2e76b3b219fc7c6d25ad234c97ad03d1f61b9f90c6a27a1"
- file:size 179183410
roles[] 1 items
- 0 "data"
json_metadata
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/json_metadata/20250706_160525_67_24c6_metadata.json"
- type "application/json"
- title "json_metadata"
- size 968
- md5_digest "4a8f154efbc725b6defb28df8208487a"
- sha256_digest "da42ee32a0e1f72f00127b5ad49508bdec36be8f4e0332883a5ace20bc022cf7"
- file:size 968
roles[] 1 items
- 0 "metadata"
basic_analytic_4b
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/basic_analytic_4b/20250706_160525_67_24c6_1B_AnalyticMS.tif"
- type "image/tiff"
- title "basic_analytic_4b"
- size 367674388
- md5_digest "e2125283bd0ee052bac22556bf23cccb"
- sha256_digest "0c208a1b5cff64ccfaf9efadb1ad524250e912bd774a29e7a6dc3bfcfa5a6bd9"
- file:size 367674388
roles[] 1 items
- 0 "data"
basic_analytic_8b
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/basic_analytic_8b/20250706_160525_67_24c6_1B_AnalyticMS_8b.tif"
- type "image/tiff"
- title "basic_analytic_8b"
- size 736624587
- md5_digest "d9cc9ef43da344eae331fe5f9c707231"
- sha256_digest "24213ab985da685fd6bb75a71ef800721cf21d4dea9058fbf414b5b86cb15afb"
- file:size 736624587
roles[] 1 items
- 0 "data"
ortho_analytic_4b
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_analytic_4b/20250706_160525_67_24c6_3B_AnalyticMS.tif"
- type "image/tiff"
- title "ortho_analytic_4b"
- size 518181162
- md5_digest "f71ff41d20ec02773e7dc7b39d1f5faf"
- sha256_digest "cceafa53d129db6a6bf830ec4888fa49a434502b0cf92485d94e9d4104465aa6"
- file:size 518181162
roles[] 1 items
- 0 "data"
ortho_analytic_8b
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_analytic_8b/20250706_160525_67_24c6_3B_AnalyticMS_8b.tif"
- type "image/tiff"
- title "ortho_analytic_8b"
- size 1029523389
- md5_digest "cbe5197d05b89928660ae49ae815aae9"
- sha256_digest "d57c75052733ce884701a1b74a05d6f9524156cc6eb649b886513d01d7996287"
- file:size 1029523389
roles[] 1 items
- 0 "data"
ortho_analytic_4b_sr
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_analytic_4b_sr/20250706_160525_67_24c6_3B_AnalyticMS_SR.tif"
- type "image/tiff"
- title "ortho_analytic_4b_sr"
- size 437116673
- md5_digest "bb734ff0f9f871b4df49f393b4e88d8f"
- sha256_digest "3d5ce5ab0d6b36b316a616ca5b501666e7a61e7fb6b129158588c6fc755dd524"
- file:size 437116673
roles[] 1 items
- 0 "data"
ortho_analytic_8b_sr
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_analytic_8b_sr/20250706_160525_67_24c6_3B_AnalyticMS_SR_8b.tif"
- type "image/tiff"
- title "ortho_analytic_8b_sr"
- size 866996013
- md5_digest "0625a9a579ee6f0f23b440d94ab6da01"
- sha256_digest "d8807569ffbc9b9b58d2a91e1216bf382a6224a01e658caa6c55aa78d11fab65"
- file:size 866996013
roles[] 1 items
- 0 "data"
basic_analytic_4b_rpc
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/basic_analytic_4b_rpc/20250706_160525_67_24c6_1B_AnalyticMS_RPC.TXT"
- type "text/plain"
- title "basic_analytic_4b_rpc"
- size 3327
- md5_digest "d1cc47badc61e297083d6f5c38e5fec9"
- sha256_digest "de1853f78c4c258130e8c29de3449db6c3d99fb211c70bef6950288984824ea4"
- file:size 3327
roles[] 1 items
- 0 "data"
basic_analytic_4b_xml
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/basic_analytic_4b_xml/20250706_160525_67_24c6_1B_AnalyticMS_metadata.xml"
- type "text/xml"
- title "basic_analytic_4b_xml"
- size 10273
- md5_digest "cfbd62268f7817d15f6d309487e61132"
- sha256_digest "66ec44fe1088a72cf91d04b0e1efe645f77c2735dc43235a141dd49ac9211ff9"
- file:size 10273
roles[] 1 items
- 0 "metadata"
basic_analytic_8b_xml
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/basic_analytic_8b_xml/20250706_160525_67_24c6_1B_AnalyticMS_8b_metadata.xml"
- type "text/xml"
- title "basic_analytic_8b_xml"
- size 12153
- md5_digest "a50547fc08e1f85b3961ddf412c9896d"
- sha256_digest "c3c2a1494b3181652d562fa271293bbd14e0d6a461e67bf6e90f4ec028d939c8"
- file:size 12153
roles[] 1 items
- 0 "metadata"
ortho_analytic_4b_xml
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_analytic_4b_xml/20250706_160525_67_24c6_3B_AnalyticMS_metadata.xml"
- type "text/xml"
- title "ortho_analytic_4b_xml"
- size 10288
- md5_digest "0042fda1590909d48865600a16cdb418"
- sha256_digest "5972e578f366cb01898086813110b9dc07f5a317193b3672c725a9f4cbfd97c3"
- file:size 10288
roles[] 1 items
- 0 "metadata"
ortho_analytic_8b_xml
- href "s3://ss-ingest-prod-ingesteddata-uswest2/storage-ss-ingest-prod-ingesteddata-uswest2/planet/PSScene-20250706_160525_67_24c6/assets/ortho_analytic_8b_xml/20250706_160525_67_24c6_3B_AnalyticMS_8b_metadata.xml"
- type "text/xml"
- title "ortho_analytic_8b_xml"
- size 12168
- md5_digest "f6fa07ea75fea5fda2a879260f73ed28"
- sha256_digest "479f6cd3a30100ba958944653a8ef5bcbd4abbd13ffbd9e53dc6e0c89cc6157a"
- file:size 12168
roles[] 1 items
- 0 "metadata"
- collection "planet"
Download assets¶
While the STAC API is open, the CSDA Orders API requires authentication. You'll use your Earthdata login username and password to log in.
username = input("Earthdata username: ")
password = getpass.getpass("Earthdata password: ")
Logging into CSDA creates an access token that encodes your download quotas, among other information.
client = CsdaClient.open(BasicAuth(username=username, password=password))
client.verify()
'Hello gadomski, you have a valid token!'
First, let's see how much quota you have. The example output has very large quotas, because it was run for a developer on the project who has artificially high quotas.
profile = client.profile(username)
rows = []
for vendor in profile.vendors:
rows.append([vendor.vendor, vendor.quota, vendor.quota_unit])
tabulate.tabulate(rows, headers=["Vendor", "Quota", "Quota unit"], tablefmt="html")
| Vendor | Quota | Quota unit |
|---|---|---|
| BlackSky | 1099511627776 | QuotaUnit.filesize |
| GHGSat | 1099511627776 | QuotaUnit.filesize |
| EarthDEM | 21990232555520 | QuotaUnit.filesize |
| Airbus U.S. | 1099511627776 | QuotaUnit.filesize |
| Spire | 1099511627776 | QuotaUnit.filesize |
| Planet | 5000000 | QuotaUnit.area |
| Umbra | 1099511627776 | QuotaUnit.filesize |
To create a new order, let's first identify the item ids that we want to order. For cost-saving, we regularly move "older" data (data that was provided to the program a long time ago) to "cold" storage, meaning that it can't be quickly downloaded. For this demonstration, we cheat a bit and use an item that we know isn't in cold storage (for now).
item_search = stac_client.search(
collections=["planet"],
ids=["PSScene-20250513_160742_95_253a"],
)
item_collection = item_search.item_collection()
assert len(item_collection) == 1
data_frame = GeoDataFrame.from_features(item_collection.to_dict())
data_frame
| geometry | eo:gsd | datetime | eo:bands | eo:azimuth | pl:updated | pl:provider | pl:strip_id | eo:off_nadir | pl:item_type | ... | pl:visible_percent | pl:anomalous_pixels | pl:pixel_resolution | pl:publishing_stage | pl:quality_category | pl:snow_ice_percent | pl:heavy_haze_percent | pl:light_haze_percent | pl:clear_confidence_percent | pl:visible_confidence_percent | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | POLYGON ((-72.47785 42.70292, -72.5326 42.5210... | 3.9 | 2025-05-13T16:07:42.957137Z | [] | 270.6 | 2025-05-14T03:55:05Z | planetscope | 8063802 | 1.2 | PSScene | ... | 94 | 0 | 3 | finalized | standard | 0 | 0 | 79 | 80 | 71 |
1 rows × 30 columns
The item has several assets.
item = item_collection[0]
rows = []
for key, asset in item.assets.items():
if file_size := asset.ext.file.size:
humanized_file_size = humanize.naturalsize(file_size)
else:
humanized_file_size = None
if roles := asset.roles:
humanized_roles = humanize.natural_list(roles)
else:
humanized_roles = roles
rows.append([key, humanized_roles, asset.media_type, humanized_file_size])
tabulate.tabulate(
rows, headers=["Key", "Roles", "Type", "File size", "Roles"], tablefmt="html"
)
| Key | Roles | Type | File size |
|---|---|---|---|
| thumbnail | thumbnail | ||
| basic_udm2 | data | image/tiff | 4.6 MB |
| ortho_udm2 | data | image/tiff | 8.2 MB |
| ortho_visual | data | image/tiff | 200.3 MB |
| json_metadata | metadata | application/json | 975 Bytes |
| basic_analytic_4b | data | image/tiff | 352.6 MB |
| basic_analytic_8b | data | image/tiff | 714.4 MB |
| ortho_analytic_4b | data | image/tiff | 586.8 MB |
| ortho_analytic_8b | data | image/tiff | 1.2 GB |
| ortho_analytic_4b_sr | data | image/tiff | 494.2 MB |
| ortho_analytic_8b_sr | data | image/tiff | 989.4 MB |
| basic_analytic_4b_rpc | data | text/plain | 3.3 kB |
| basic_analytic_4b_xml | metadata | text/xml | 10.3 kB |
| basic_analytic_8b_xml | metadata | text/xml | 12.2 kB |
| ortho_analytic_4b_xml | metadata | text/xml | 10.3 kB |
| ortho_analytic_8b_xml | metadata | text/xml | 12.2 kB |
Let's download the ortho visual asset.
with TemporaryDirectory() as temporary_directory:
local_path = Path(temporary_directory) / "ortho_visual.tif"
client.download_item(item, "ortho_visual", local_path)
with rasterio.open(local_path) as dataset:
rasterio.plot.show(dataset)