rsplot 0.2.7__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rsplot-0.2.7 → rsplot-0.3.1}/PKG-INFO +115 -12
- rsplot-0.3.1/README.md +250 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/pyproject.toml +9 -2
- rsplot-0.3.1/src/rsplot/__init__.py +10 -0
- rsplot-0.3.1/src/rsplot/cli.py +937 -0
- rsplot-0.3.1/src/rsplot/commands/__init__.py +1 -0
- rsplot-0.3.1/src/rsplot/commands/common.py +112 -0
- rsplot-0.3.1/src/rsplot/commands/fnr.py +262 -0
- rsplot-0.3.1/src/rsplot/commands/forecast.py +349 -0
- rsplot-0.3.1/src/rsplot/commands/meteo.py +381 -0
- rsplot-0.3.1/src/rsplot/commands/overlay.py +267 -0
- rsplot-0.3.1/src/rsplot/commands/raster.py +386 -0
- rsplot-0.3.1/src/rsplot/commands/recent.py +164 -0
- rsplot-0.3.1/src/rsplot/commands/reconstruct.py +220 -0
- rsplot-0.3.1/src/rsplot/commands/station.py +135 -0
- rsplot-0.3.1/src/rsplot/commands/station_trend.py +317 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/config.py +46 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/fnr.py +66 -159
- rsplot-0.3.1/src/rsplot/geo/boundaries.py +474 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/geo/gridding.py +12 -4
- rsplot-0.3.1/src/rsplot/geo/processing.py +120 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/plotting/fnr.py +18 -91
- rsplot-0.2.7/src/rsplot/plotting/raster.py → rsplot-0.3.1/src/rsplot/plotting/map_frame.py +116 -119
- rsplot-0.3.1/src/rsplot/plotting/meteo.py +158 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/plotting/overlay.py +30 -101
- rsplot-0.3.1/src/rsplot/plotting/raster.py +103 -0
- rsplot-0.3.1/src/rsplot/plotting/station.py +172 -0
- rsplot-0.3.1/src/rsplot/plotting/station_trend.py +320 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/plotting/styles.py +7 -6
- rsplot-0.3.1/src/rsplot/plotting/wind.py +80 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/readers/__init__.py +3 -1
- rsplot-0.3.1/src/rsplot/readers/_tropomi.py +130 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/readers/base.py +66 -0
- rsplot-0.3.1/src/rsplot/readers/era5.py +201 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/readers/era5_wind.py +21 -70
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/readers/forecast.py +61 -27
- rsplot-0.3.1/src/rsplot/readers/guokong.py +451 -0
- rsplot-0.3.1/src/rsplot/readers/reconstruct.py +436 -0
- rsplot-0.3.1/src/rsplot/readers/tropomi_hcho.py +32 -0
- rsplot-0.3.1/src/rsplot/readers/tropomi_no2.py +33 -0
- rsplot-0.3.1/src/rsplot/readers/tropomi_o3.py +35 -0
- rsplot-0.3.1/src/rsplot/readers/tropomi_o3pr.py +33 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/recent.py +43 -61
- rsplot-0.3.1/src/rsplot/result_builders/__init__.py +25 -0
- rsplot-0.3.1/src/rsplot/result_builders/common.py +138 -0
- rsplot-0.3.1/src/rsplot/result_builders/fnr.py +189 -0
- rsplot-0.3.1/src/rsplot/result_builders/forecast.py +113 -0
- rsplot-0.3.1/src/rsplot/result_builders/meteo.py +171 -0
- rsplot-0.3.1/src/rsplot/result_builders/overlay.py +75 -0
- rsplot-0.3.1/src/rsplot/result_builders/raster.py +72 -0
- rsplot-0.3.1/src/rsplot/result_builders/reconstruct.py +85 -0
- rsplot-0.3.1/src/rsplot/result_builders/station.py +221 -0
- rsplot-0.3.1/src/rsplot/result_builders/station_trend.py +229 -0
- rsplot-0.3.1/src/rsplot/results.py +45 -0
- rsplot-0.3.1/src/rsplot/stats.py +36 -0
- rsplot-0.3.1/src/rsplot/temporal.py +224 -0
- rsplot-0.2.7/README.md +0 -147
- rsplot-0.2.7/src/rsplot/__init__.py +0 -3
- rsplot-0.2.7/src/rsplot/cli.py +0 -1939
- rsplot-0.2.7/src/rsplot/geo/boundaries.py +0 -281
- rsplot-0.2.7/src/rsplot/plotting/station.py +0 -329
- rsplot-0.2.7/src/rsplot/readers/guokong.py +0 -143
- rsplot-0.2.7/src/rsplot/readers/tropomi_hcho.py +0 -126
- rsplot-0.2.7/src/rsplot/readers/tropomi_no2.py +0 -102
- rsplot-0.2.7/src/rsplot/readers/tropomi_o3.py +0 -104
- rsplot-0.2.7/src/rsplot/readers/tropomi_o3pr.py +0 -103
- rsplot-0.2.7/src/rsplot/results.py +0 -793
- {rsplot-0.2.7 → rsplot-0.3.1}/.gitignore +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/LICENSE +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/__main__.py +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/geo/__init__.py +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/plotting/__init__.py +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/plotting/colormaps.py +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/tiles/__init__.py +0 -0
- {rsplot-0.2.7 → rsplot-0.3.1}/src/rsplot/tiles/tianditu.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: rsplot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: CLI tool for plotting Remote Sensing data, designed for Agent.
|
|
5
5
|
Project-URL: Repository, https://git.lug.ustc.edu.cn/yaoyhu/rsplot
|
|
6
6
|
Project-URL: GitHub, https://github.com/yaoyhu/rsplot
|
|
@@ -227,8 +227,8 @@ Description-Content-Type: text/markdown
|
|
|
227
227
|
|
|
228
228
|
# rsplot
|
|
229
229
|
|
|
230
|
-
`rsplot` is an Agent-oriented command-line tool for plotting remote-sensing
|
|
231
|
-
air-quality data. It
|
|
230
|
+
`rsplot` is an Agent-oriented command-line tool for plotting remote-sensing,
|
|
231
|
+
reconstructed, and air-quality data. It provides a small, stable CLI surface for
|
|
232
232
|
[tianpu-agent](https://git.lug.ustc.edu.cn/yaoyhu/tianpu-agent).
|
|
233
233
|
|
|
234
234
|
|
|
@@ -247,6 +247,19 @@ uv add rsplot
|
|
|
247
247
|
uv run rsplot --help
|
|
248
248
|
```
|
|
249
249
|
|
|
250
|
+
### Development releases
|
|
251
|
+
|
|
252
|
+
Every push to `main` publishes a PEP 440 development release such as
|
|
253
|
+
`0.3.1.dev4`. Stable installs continue to ignore these releases. To follow the
|
|
254
|
+
latest development build, opt in once:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
uv tool install rsplot --prerelease allow
|
|
258
|
+
uv tool upgrade rsplot
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The prerelease setting is retained by later `uv tool upgrade` commands.
|
|
262
|
+
|
|
250
263
|
For local development:
|
|
251
264
|
|
|
252
265
|
```bash
|
|
@@ -282,6 +295,13 @@ hcho = "/path/to/HCHO"
|
|
|
282
295
|
guokong = "/path/to/guokong_combine"
|
|
283
296
|
era5 = "/path/to/era5"
|
|
284
297
|
forecast = "/path/to/forecast"
|
|
298
|
+
reconstruct = "/path/to/reconstruct"
|
|
299
|
+
|
|
300
|
+
# Optional lower-level boundary override for a direct-administered city.
|
|
301
|
+
# [subdivision_overrides."中山市"]
|
|
302
|
+
# path = "/path/to/中山市镇街界线.shp"
|
|
303
|
+
# name_field = "镇街名称"
|
|
304
|
+
# level = "township"
|
|
285
305
|
|
|
286
306
|
# Optional satellite basemap key. Leave commented unless you have a real key.
|
|
287
307
|
# [tianditu]
|
|
@@ -307,6 +327,7 @@ export RSPLOT_DATA_DIR_HCHO="/path/to/HCHO"
|
|
|
307
327
|
export RSPLOT_DATA_DIR_GUOKONG="/path/to/guokong_combine"
|
|
308
328
|
export RSPLOT_DATA_DIR_ERA5="/path/to/era5"
|
|
309
329
|
export RSPLOT_DATA_DIR_FORECAST="/path/to/forecast"
|
|
330
|
+
export RSPLOT_DATA_DIR_RECONSTRUCT="/path/to/reconstruct"
|
|
310
331
|
export RSPLOT_HCHO_CMAP_FILE="/path/to/256x3_rgb_table.txt"
|
|
311
332
|
```
|
|
312
333
|
|
|
@@ -314,6 +335,11 @@ Command-line directory options, such as `--data-dir`, take precedence for the
|
|
|
314
335
|
command being run. If no TianDiTu API key is configured, use `--basemap none`
|
|
315
336
|
to avoid requesting satellite tiles.
|
|
316
337
|
|
|
338
|
+
City subdivision overrides replace the county layer only for the configured
|
|
339
|
+
city. Their source CRS is converted to the CRS of the standard city boundary.
|
|
340
|
+
This lets direct-administered towns or streets appear in maps and spatial
|
|
341
|
+
summaries, and makes qualified inputs such as `中山/板芙` resolvable.
|
|
342
|
+
|
|
317
343
|
## Usage
|
|
318
344
|
|
|
319
345
|
The examples below assume data paths are configured and readable.
|
|
@@ -334,24 +360,63 @@ rsplot raster 安徽 20260227 -p o3pr -o o3pr_anhui_20260227.png
|
|
|
334
360
|
# Plot an explicit TROPOMI date range.
|
|
335
361
|
rsplot raster 长三角 20260101-20260131 -p no2 -o no2_yrd_202601.png
|
|
336
362
|
|
|
337
|
-
#
|
|
363
|
+
# Reconstructed-grid input is China standard time; rsplot converts it to the
|
|
364
|
+
# matching UTC archive filename. This reads 2026051100.nc.
|
|
365
|
+
rsplot reconstruct 安徽 2026051108 --var PM2.5 \
|
|
366
|
+
-o reconstruct_anhui_pm25.png
|
|
367
|
+
|
|
368
|
+
# Date-only input selects the latest complete hour in that China-time day.
|
|
369
|
+
rsplot reconstruct 合肥 20260511 --var O3 --res 0.01 \
|
|
370
|
+
-o reconstruct_hefei_o3.png
|
|
371
|
+
|
|
372
|
+
# Forecast input is China standard time; rsplot converts it
|
|
373
|
+
# to the matching UTC archive initialization hour before reading.
|
|
338
374
|
rsplot forecast 安徽 2026063000 --lead 24 --var O3 -o forecast_anhui_o3.png
|
|
339
375
|
|
|
340
|
-
# Date-only
|
|
376
|
+
# Date-only input selects the latest initialization within that China-time day.
|
|
341
377
|
rsplot forecast 合肥 20260630 --lead 72 --var PM2.5 -o forecast_hefei_pm25.png
|
|
342
378
|
|
|
343
379
|
# Overlay station observations on the forecast valid time.
|
|
344
380
|
rsplot forecast 合肥 2026041409 --lead 6 --var O3 --station-overlay -o forecast_station_hefei_o3.png
|
|
345
381
|
|
|
382
|
+
# Plot ERA5 2 m temperature. Input hours are China standard time; rsplot
|
|
383
|
+
# converts them to the matching UTC archive day and hour automatically.
|
|
384
|
+
rsplot meteo 南京 2026051115 --temp-level 2m -o meteo_nanjing_t2m.png
|
|
385
|
+
|
|
386
|
+
# Plot black 850 hPa wind arrows; length represents speed and no wind
|
|
387
|
+
# colorbar is drawn. The reference arrow gives the speed scale.
|
|
388
|
+
rsplot meteo 南京 2026051115 --wind-level 850 -o meteo_nanjing_wind850.png
|
|
389
|
+
|
|
390
|
+
# Overlay black wind arrows on a temperature background. Only the temperature
|
|
391
|
+
# colorbar is drawn.
|
|
392
|
+
rsplot meteo 南京 2026051115 --temp-level 850 \
|
|
393
|
+
--wind-level 850 -o meteo_nanjing_t850_wind850.png
|
|
394
|
+
|
|
395
|
+
# Overlay station observations with black wind arrows.
|
|
396
|
+
rsplot meteo 南京 2026051115 --station-var O3 \
|
|
397
|
+
--wind-level 850 -o meteo_nanjing_o3_wind850.png
|
|
398
|
+
|
|
399
|
+
# Temperature, stations, and wind can be combined. The two colorbars describe
|
|
400
|
+
# temperature and station concentration; wind magnitude is encoded by length.
|
|
401
|
+
rsplot meteo 南京 2026051115 --temp-level 850 --station-var O3 \
|
|
402
|
+
--wind-level 850 -o meteo_nanjing_t850_o3_wind850.png
|
|
403
|
+
|
|
346
404
|
# Plot national monitoring station observations.
|
|
347
405
|
rsplot station 合肥 2026041415 --var O3 -o station_hefei_o3.png
|
|
348
406
|
|
|
349
|
-
#
|
|
350
|
-
|
|
351
|
-
rsplot station 合肥 2026041415 --var O3 --wind-level 10m -o station_wind_hefei_o3.png
|
|
407
|
+
# Plot one station's hourly observations over the latest seven days.
|
|
408
|
+
rsplot trend 3347A 20260520 --days 7 --var O3 -o trend_3347A_o3_7d.png
|
|
352
409
|
|
|
353
|
-
#
|
|
354
|
-
rsplot
|
|
410
|
+
# A single day and an explicit date range are also supported.
|
|
411
|
+
rsplot trend 3347A 20260520 --days 1 --var O3 -o trend_3347A_o3_day.png
|
|
412
|
+
rsplot trend 3347A 20260501-20260507 --var PM2.5 -o trend_3347A_pm25.png
|
|
413
|
+
|
|
414
|
+
# Plot all regional stations as grey lines plus the hourly station mean.
|
|
415
|
+
rsplot trend 重庆 20260520 --days 7 --var O3 --region -o trend_chongqing_o3.png
|
|
416
|
+
|
|
417
|
+
# Plot only the regional mean and highlight one or more explicit stations.
|
|
418
|
+
rsplot trend 重庆 20260520 --days 7 --var O3 --region --view mean \
|
|
419
|
+
--focus-station 3347A --threshold 200 -o trend_chongqing_focus.png
|
|
355
420
|
|
|
356
421
|
# Overlay satellite raster data and station observations.
|
|
357
422
|
rsplot overlay 合肥 2026041415 -p no2 --var NO2 -o overlay_hefei_no2.png
|
|
@@ -367,8 +432,46 @@ rsplot fnr 合肥 20260114 --voc-threshold 0.8 --nox-threshold 1.8 --display-max
|
|
|
367
432
|
```
|
|
368
433
|
|
|
369
434
|
When `-o/--output` is provided, `rsplot` writes the image to that path and also
|
|
370
|
-
writes a JSON sidecar with the same base name.
|
|
435
|
+
writes a JSON sidecar with the same base name. Reconstructed-grid JSON records
|
|
436
|
+
both the China-time input and matched UTC archive hour, source file, native and
|
|
437
|
+
output resolution, regional statistics, administrative summaries, and hotspots.
|
|
371
438
|
|
|
372
439
|
## License
|
|
373
440
|
|
|
374
441
|
This project is distributed under the license in `LICENSE`.
|
|
442
|
+
|
|
443
|
+
## Publishing
|
|
444
|
+
|
|
445
|
+
The package version is derived from Git by `hatch-vcs`; do not add a static
|
|
446
|
+
`project.version` or make version-bump commits. The latest `vX.Y.Z` tag is the
|
|
447
|
+
stable version. Commits after it build as the next patch development series:
|
|
448
|
+
|
|
449
|
+
```text
|
|
450
|
+
v0.3.0 -> 0.3.0
|
|
451
|
+
first commit -> 0.3.1.dev1
|
|
452
|
+
second commit -> 0.3.1.dev2
|
|
453
|
+
v0.3.1 -> 0.3.1
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
GitHub Actions publishes every `main` push through the `pypi-dev` environment
|
|
457
|
+
and every `v*` tag through `pypi`. Configure two PyPI Trusted Publishers with
|
|
458
|
+
the same owner, repository, and workflow, differing only by environment:
|
|
459
|
+
|
|
460
|
+
```text
|
|
461
|
+
Owner: yaoyhu
|
|
462
|
+
Repository: rsplot
|
|
463
|
+
Workflow: publish.yml
|
|
464
|
+
Environment: pypi-dev
|
|
465
|
+
Environment: pypi
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Leave `pypi-dev` automatic for continuous development uploads. Protect the
|
|
469
|
+
`pypi` GitHub environment with required reviewers so stable releases need an
|
|
470
|
+
explicit approval.
|
|
471
|
+
|
|
472
|
+
To make a stable release after the desired commit is on GitHub:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
git tag -a v0.3.1 -m v0.3.1
|
|
476
|
+
git push github v0.3.1
|
|
477
|
+
```
|
rsplot-0.3.1/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# rsplot
|
|
2
|
+
|
|
3
|
+
`rsplot` is an Agent-oriented command-line tool for plotting remote-sensing,
|
|
4
|
+
reconstructed, and air-quality data. It provides a small, stable CLI surface for
|
|
5
|
+
[tianpu-agent](https://git.lug.ustc.edu.cn/yaoyhu/tianpu-agent).
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Run directly with `uvx`:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uvx rsplot --help
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or install it in a project environment:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv add rsplot
|
|
20
|
+
uv run rsplot --help
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Development releases
|
|
24
|
+
|
|
25
|
+
Every push to `main` publishes a PEP 440 development release such as
|
|
26
|
+
`0.3.1.dev4`. Stable installs continue to ignore these releases. To follow the
|
|
27
|
+
latest development build, opt in once:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv tool install rsplot --prerelease allow
|
|
31
|
+
uv tool upgrade rsplot
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The prerelease setting is retained by later `uv tool upgrade` commands.
|
|
35
|
+
|
|
36
|
+
For local development:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/yaoyhu/rsplot.git
|
|
40
|
+
cd rsplot
|
|
41
|
+
uv sync
|
|
42
|
+
uv run rsplot --help
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Configuration
|
|
46
|
+
|
|
47
|
+
`rsplot` does not ship site-specific data paths. Configure local satellite,
|
|
48
|
+
station, boundary, and font paths with a TOML file:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
mkdir -p ~/.config/rsplot
|
|
52
|
+
cp config.example.toml ~/.config/rsplot/config.toml
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then edit `~/.config/rsplot/config.toml`:
|
|
56
|
+
|
|
57
|
+
```toml
|
|
58
|
+
[paths]
|
|
59
|
+
geojson_dir = "/path/to/geojson"
|
|
60
|
+
font_dir = "/path/to/fonts"
|
|
61
|
+
# hcho_cmap_file = "/path/to/256x3_rgb_table.txt"
|
|
62
|
+
|
|
63
|
+
[paths.data_dirs]
|
|
64
|
+
no2 = "/path/to/NO2"
|
|
65
|
+
o3 = "/path/to/O3"
|
|
66
|
+
o3pr = "/path/to/O3PR"
|
|
67
|
+
hcho = "/path/to/HCHO"
|
|
68
|
+
guokong = "/path/to/guokong_combine"
|
|
69
|
+
era5 = "/path/to/era5"
|
|
70
|
+
forecast = "/path/to/forecast"
|
|
71
|
+
reconstruct = "/path/to/reconstruct"
|
|
72
|
+
|
|
73
|
+
# Optional lower-level boundary override for a direct-administered city.
|
|
74
|
+
# [subdivision_overrides."中山市"]
|
|
75
|
+
# path = "/path/to/中山市镇街界线.shp"
|
|
76
|
+
# name_field = "镇街名称"
|
|
77
|
+
# level = "township"
|
|
78
|
+
|
|
79
|
+
# Optional satellite basemap key. Leave commented unless you have a real key.
|
|
80
|
+
# [tianditu]
|
|
81
|
+
# api_key = "your-real-key"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
You can also point to a different config file:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
export RSPLOT_CONFIG="/path/to/rsplot.toml"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Environment variables override TOML values:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
export TIANDITU_API_KEY="your-key"
|
|
94
|
+
export RSPLOT_GEOJSON_DIR="/path/to/geojson"
|
|
95
|
+
export RSPLOT_FONT_DIR="/path/to/fonts"
|
|
96
|
+
export RSPLOT_DATA_DIR_NO2="/path/to/NO2"
|
|
97
|
+
export RSPLOT_DATA_DIR_O3="/path/to/O3"
|
|
98
|
+
export RSPLOT_DATA_DIR_O3PR="/path/to/O3PR"
|
|
99
|
+
export RSPLOT_DATA_DIR_HCHO="/path/to/HCHO"
|
|
100
|
+
export RSPLOT_DATA_DIR_GUOKONG="/path/to/guokong_combine"
|
|
101
|
+
export RSPLOT_DATA_DIR_ERA5="/path/to/era5"
|
|
102
|
+
export RSPLOT_DATA_DIR_FORECAST="/path/to/forecast"
|
|
103
|
+
export RSPLOT_DATA_DIR_RECONSTRUCT="/path/to/reconstruct"
|
|
104
|
+
export RSPLOT_HCHO_CMAP_FILE="/path/to/256x3_rgb_table.txt"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Command-line directory options, such as `--data-dir`, take precedence for the
|
|
108
|
+
command being run. If no TianDiTu API key is configured, use `--basemap none`
|
|
109
|
+
to avoid requesting satellite tiles.
|
|
110
|
+
|
|
111
|
+
City subdivision overrides replace the county layer only for the configured
|
|
112
|
+
city. Their source CRS is converted to the CRS of the standard city boundary.
|
|
113
|
+
This lets direct-administered towns or streets appear in maps and spatial
|
|
114
|
+
summaries, and makes qualified inputs such as `中山/板芙` resolvable.
|
|
115
|
+
|
|
116
|
+
## Usage
|
|
117
|
+
|
|
118
|
+
The examples below assume data paths are configured and readable.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Show available commands and options.
|
|
122
|
+
rsplot --help
|
|
123
|
+
|
|
124
|
+
# Plot a single-day TROPOMI raster.
|
|
125
|
+
rsplot raster 合肥 20260115 -p no2 -o ./logs/hcho/raster_city_jiujiang_hcho.png
|
|
126
|
+
|
|
127
|
+
# Plot a 30-day TROPOMI window mean.
|
|
128
|
+
rsplot raster 安徽 20260131 -p hcho --days 30 -o hcho_anhui_202601.png
|
|
129
|
+
|
|
130
|
+
# Plot a TROPOMI ozone-profile tropospheric column raster.
|
|
131
|
+
rsplot raster 安徽 20260227 -p o3pr -o o3pr_anhui_20260227.png
|
|
132
|
+
|
|
133
|
+
# Plot an explicit TROPOMI date range.
|
|
134
|
+
rsplot raster 长三角 20260101-20260131 -p no2 -o no2_yrd_202601.png
|
|
135
|
+
|
|
136
|
+
# Reconstructed-grid input is China standard time; rsplot converts it to the
|
|
137
|
+
# matching UTC archive filename. This reads 2026051100.nc.
|
|
138
|
+
rsplot reconstruct 安徽 2026051108 --var PM2.5 \
|
|
139
|
+
-o reconstruct_anhui_pm25.png
|
|
140
|
+
|
|
141
|
+
# Date-only input selects the latest complete hour in that China-time day.
|
|
142
|
+
rsplot reconstruct 合肥 20260511 --var O3 --res 0.01 \
|
|
143
|
+
-o reconstruct_hefei_o3.png
|
|
144
|
+
|
|
145
|
+
# Forecast input is China standard time; rsplot converts it
|
|
146
|
+
# to the matching UTC archive initialization hour before reading.
|
|
147
|
+
rsplot forecast 安徽 2026063000 --lead 24 --var O3 -o forecast_anhui_o3.png
|
|
148
|
+
|
|
149
|
+
# Date-only input selects the latest initialization within that China-time day.
|
|
150
|
+
rsplot forecast 合肥 20260630 --lead 72 --var PM2.5 -o forecast_hefei_pm25.png
|
|
151
|
+
|
|
152
|
+
# Overlay station observations on the forecast valid time.
|
|
153
|
+
rsplot forecast 合肥 2026041409 --lead 6 --var O3 --station-overlay -o forecast_station_hefei_o3.png
|
|
154
|
+
|
|
155
|
+
# Plot ERA5 2 m temperature. Input hours are China standard time; rsplot
|
|
156
|
+
# converts them to the matching UTC archive day and hour automatically.
|
|
157
|
+
rsplot meteo 南京 2026051115 --temp-level 2m -o meteo_nanjing_t2m.png
|
|
158
|
+
|
|
159
|
+
# Plot black 850 hPa wind arrows; length represents speed and no wind
|
|
160
|
+
# colorbar is drawn. The reference arrow gives the speed scale.
|
|
161
|
+
rsplot meteo 南京 2026051115 --wind-level 850 -o meteo_nanjing_wind850.png
|
|
162
|
+
|
|
163
|
+
# Overlay black wind arrows on a temperature background. Only the temperature
|
|
164
|
+
# colorbar is drawn.
|
|
165
|
+
rsplot meteo 南京 2026051115 --temp-level 850 \
|
|
166
|
+
--wind-level 850 -o meteo_nanjing_t850_wind850.png
|
|
167
|
+
|
|
168
|
+
# Overlay station observations with black wind arrows.
|
|
169
|
+
rsplot meteo 南京 2026051115 --station-var O3 \
|
|
170
|
+
--wind-level 850 -o meteo_nanjing_o3_wind850.png
|
|
171
|
+
|
|
172
|
+
# Temperature, stations, and wind can be combined. The two colorbars describe
|
|
173
|
+
# temperature and station concentration; wind magnitude is encoded by length.
|
|
174
|
+
rsplot meteo 南京 2026051115 --temp-level 850 --station-var O3 \
|
|
175
|
+
--wind-level 850 -o meteo_nanjing_t850_o3_wind850.png
|
|
176
|
+
|
|
177
|
+
# Plot national monitoring station observations.
|
|
178
|
+
rsplot station 合肥 2026041415 --var O3 -o station_hefei_o3.png
|
|
179
|
+
|
|
180
|
+
# Plot one station's hourly observations over the latest seven days.
|
|
181
|
+
rsplot trend 3347A 20260520 --days 7 --var O3 -o trend_3347A_o3_7d.png
|
|
182
|
+
|
|
183
|
+
# A single day and an explicit date range are also supported.
|
|
184
|
+
rsplot trend 3347A 20260520 --days 1 --var O3 -o trend_3347A_o3_day.png
|
|
185
|
+
rsplot trend 3347A 20260501-20260507 --var PM2.5 -o trend_3347A_pm25.png
|
|
186
|
+
|
|
187
|
+
# Plot all regional stations as grey lines plus the hourly station mean.
|
|
188
|
+
rsplot trend 重庆 20260520 --days 7 --var O3 --region -o trend_chongqing_o3.png
|
|
189
|
+
|
|
190
|
+
# Plot only the regional mean and highlight one or more explicit stations.
|
|
191
|
+
rsplot trend 重庆 20260520 --days 7 --var O3 --region --view mean \
|
|
192
|
+
--focus-station 3347A --threshold 200 -o trend_chongqing_focus.png
|
|
193
|
+
|
|
194
|
+
# Overlay satellite raster data and station observations.
|
|
195
|
+
rsplot overlay 合肥 2026041415 -p no2 --var NO2 -o overlay_hefei_no2.png
|
|
196
|
+
|
|
197
|
+
# Plot an FNR regime map with the default 7-day window.
|
|
198
|
+
rsplot fnr 合肥 20260114 -o fnr_hefei.png
|
|
199
|
+
|
|
200
|
+
# Plot an FNR regime map with an explicit date range.
|
|
201
|
+
rsplot fnr 长三角 20260101-20260130 -o fnr_yrd_202601.png
|
|
202
|
+
|
|
203
|
+
# Override FNR regime thresholds for agent-driven sensitivity tests.
|
|
204
|
+
rsplot fnr 合肥 20260114 --voc-threshold 0.8 --nox-threshold 1.8 --display-max 5 -o fnr_hefei_sensitivity.png
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
When `-o/--output` is provided, `rsplot` writes the image to that path and also
|
|
208
|
+
writes a JSON sidecar with the same base name. Reconstructed-grid JSON records
|
|
209
|
+
both the China-time input and matched UTC archive hour, source file, native and
|
|
210
|
+
output resolution, regional statistics, administrative summaries, and hotspots.
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
This project is distributed under the license in `LICENSE`.
|
|
215
|
+
|
|
216
|
+
## Publishing
|
|
217
|
+
|
|
218
|
+
The package version is derived from Git by `hatch-vcs`; do not add a static
|
|
219
|
+
`project.version` or make version-bump commits. The latest `vX.Y.Z` tag is the
|
|
220
|
+
stable version. Commits after it build as the next patch development series:
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
v0.3.0 -> 0.3.0
|
|
224
|
+
first commit -> 0.3.1.dev1
|
|
225
|
+
second commit -> 0.3.1.dev2
|
|
226
|
+
v0.3.1 -> 0.3.1
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
GitHub Actions publishes every `main` push through the `pypi-dev` environment
|
|
230
|
+
and every `v*` tag through `pypi`. Configure two PyPI Trusted Publishers with
|
|
231
|
+
the same owner, repository, and workflow, differing only by environment:
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
Owner: yaoyhu
|
|
235
|
+
Repository: rsplot
|
|
236
|
+
Workflow: publish.yml
|
|
237
|
+
Environment: pypi-dev
|
|
238
|
+
Environment: pypi
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Leave `pypi-dev` automatic for continuous development uploads. Protect the
|
|
242
|
+
`pypi` GitHub environment with required reviewers so stable releases need an
|
|
243
|
+
explicit approval.
|
|
244
|
+
|
|
245
|
+
To make a stable release after the desired commit is on GitHub:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
git tag -a v0.3.1 -m v0.3.1
|
|
249
|
+
git push github v0.3.1
|
|
250
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "rsplot"
|
|
3
|
-
|
|
3
|
+
dynamic = ["version"]
|
|
4
4
|
description = "CLI tool for plotting Remote Sensing data, designed for Agent."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Yaoyao Hu", email = "yaoyhu@mail.ustc.edu.cn" },
|
|
@@ -37,9 +37,16 @@ GitHub = "https://github.com/yaoyhu/rsplot"
|
|
|
37
37
|
rsplot = "rsplot.__main__:app"
|
|
38
38
|
|
|
39
39
|
[build-system]
|
|
40
|
-
requires = ["hatchling"]
|
|
40
|
+
requires = ["hatchling", "hatch-vcs>=0.5,<0.6"]
|
|
41
41
|
build-backend = "hatchling.build"
|
|
42
42
|
|
|
43
|
+
[tool.hatch.version]
|
|
44
|
+
source = "vcs"
|
|
45
|
+
|
|
46
|
+
[tool.hatch.version.raw-options]
|
|
47
|
+
version_scheme = "guess-next-dev"
|
|
48
|
+
local_scheme = "no-local-version"
|
|
49
|
+
|
|
43
50
|
[tool.hatch.build.targets.sdist]
|
|
44
51
|
only-include = ["src/rsplot"]
|
|
45
52
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""rsplot — CLI tool for plotting Remote Sensing data, designed for agent."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
__version__ = version("rsplot")
|
|
7
|
+
except PackageNotFoundError: # pragma: no cover - source tree without install
|
|
8
|
+
__version__ = "unknown"
|
|
9
|
+
|
|
10
|
+
__all__ = ["__version__"]
|