{"id":18295887,"url":"https://github.com/astropenguin/azely","last_synced_at":"2025-04-05T12:31:46.267Z","repository":{"id":57413510,"uuid":"88344734","full_name":"astropenguin/azely","owner":"astropenguin","description":":zap: Computation and plotting of azimuth and elevation for astronomical objects","archived":false,"fork":false,"pushed_at":"2024-01-21T14:29:21.000Z","size":4197,"stargazers_count":6,"open_issues_count":9,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-05-30T01:18:07.237Z","etag":null,"topics":["astronomy","azimuth","elevation","ephemeris","python","sidereal-time","visualization"],"latest_commit_sha":null,"homepage":"https://astropenguin.github.io/azely/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/astropenguin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-15T12:12:04.000Z","updated_at":"2024-01-14T10:35:17.000Z","dependencies_parsed_at":"2024-01-20T08:32:51.326Z","dependency_job_id":"39fcc309-7ac4-48b8-be19-71511424dfb6","html_url":"https://github.com/astropenguin/azely","commit_stats":{"total_commits":774,"total_committers":2,"mean_commits":387.0,"dds":0.4018087855297158,"last_synced_commit":"c97ebe8d8986d64555cb484d4bc07b46a543a058"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fazely","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fazely/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fazely/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fazely/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/astropenguin","download_url":"https://codeload.github.com/astropenguin/azely/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247338970,"owners_count":20923002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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"}},"keywords":["astronomy","azimuth","elevation","ephemeris","python","sidereal-time","visualization"],"created_at":"2024-11-05T14:38:43.388Z","updated_at":"2025-04-05T12:31:41.247Z","avatar_url":"https://github.com/astropenguin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# azely\n\n[![Release](https://img.shields.io/pypi/v/azely?label=Release\u0026color=cornflowerblue\u0026style=flat-square)](https://pypi.org/project/azely/)\n[![Python](https://img.shields.io/pypi/pyversions/azely?label=Python\u0026color=cornflowerblue\u0026style=flat-square)](https://pypi.org/project/azely/)\n[![Downloads](https://img.shields.io/pypi/dm/azely?label=Downloads\u0026color=cornflowerblue\u0026style=flat-square)](https://pepy.tech/project/azely)\n[![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.3680060-cornflowerblue?style=flat-square)](https://doi.org/10.5281/zenodo.3680060)\n[![Tests](https://img.shields.io/github/workflow/status/astropenguin/azely/Tests?label=Tests\u0026style=flat-square)](https://github.com/astropenguin/azely/actions)\n\nComputation and plotting of azimuth and elevation for astronomical objects\n\n## TL;DR\n\nAzely (pronounced as \"as-elie\") is a Python package for computation and plotting of horizontal coordinates (azimuth and elevation; az/el, hereafter) of astronomical objects at given location and time.\nWhile computation and plotting are realized by [Astropy] and [Matplotlib], what azely provides is high-level API to use them easily.\nIn fact azely offers one-liner to compute and plot, for example, one-day elevation of the Sun in Tokyo:\n\n```python\n\u003e\u003e\u003e azely.compute('Sun', 'Tokyo').el.plot(ylim=(0, 90))\n```\n\n![one-liner.svg](https://raw.githubusercontent.com/astropenguin/azely/v0.7.0/docs/_static/one-liner.svg)\n\n## Features\n\n- **High-level API:** azely provides a simple yet powerful `compute()` function. Users can complete most of operation with it (e.g., information acquisition and computation).\n- **Handy output:** azely's output (from `compute()`) is [pandas] DataFrame, a de facto standard data structure of Python. Users can convert it to other formats like CSV and plot it by [Matplotlib] using builtin methods.\n- **Web information acquisition:** azely can automatically acquire object and location information (i.e., longitude and latitude) from online services (e.g., catalogues or maps). Obtained information is cached in a local [TOML] file for an offline use.\n- **User-defined information:** azely also offers to use user-defined object and location information written in a [TOML] file.\n\n## Requirements\n\n- **Python:** 3.7, 3.8, 3.9, and 3.10 (tested by author)\n- **Dependencies:** See [pyproject.toml](https://github.com/astropenguin/azely/blob/v0.7.0/pyproject.toml)\n\n## Installation\n\n```shell\n$ pip install azely\n```\n\n## Basic usage\n\nThis section describes basic az/el computation using `compute()` function.\n\n### Compute function\n\nAzely's `compute()` function receives the following parameters and returns [pandas] DataFrame (`df`):\n\n```python\n\u003e\u003e\u003e import azely\n\u003e\u003e\u003e df = azely.compute(object, site, time, view, **options)\n```\n\nThis means that `azely` will `compute` az/el of `object` observed from `site` at (on) `time` in `view`.\nFor example, the following code will compute az/el of Sun observed from ALMA AOS on Jan. 1st 2020 in Tokyo.\n\n```python\n\u003e\u003e\u003e df = azely.compute('Sun', 'ALMA AOS', '2020-01-01', 'Tokyo')\n```\n\nAcceptable formats of each parameter and examples are as follows.\n\n| Parameter | Acceptable format | Description | Examples |\n| --- | --- | --- | --- |\n| `object` | `\u003cobj. name\u003e` | name of object to be searched | `'Sun'`, `'NGC1068'` |\n| | `\u003ctoml\u003e:\u003cobj. name\u003e` | user-defined object to be loaded (see below) | `'user.toml:M42'`, `'user:M42'` (also valid) |\n| `site` | `'here'` (default) | current location (guess by IP address) | |\n| | `\u003cloc. name\u003e` | name of location to be searched | `'ALMA AOS'`, `'Tokyo'` |\n| | `\u003ctoml\u003e:\u003cloc. name\u003e` | user-defined location to be loaded (see below) | `'user.toml:ASTE'`, `'user:ASTE'` (also valid) |\n| `time` | `'today'` (default) | get one-day time range of today | |\n| | `'now'` | get current time | |\n| | `\u003ctime\u003e` | start time of one-day time range | `'2020-01-01'`, `'1/1 12:00'`, `'Jan. 1st'` |\n| | `\u003ctime\u003e to \u003ctime\u003e` | start and end of time range | `'1/1 to 1/3'`, `'Jan. 1st to Jan. 3rd'` |\n| `view` | `''` (default) | use timezone of `site` | |\n| | `\u003ctz name\u003e` | name of timezone database | `'Asia/Tokyo'`, `'UTC'` |\n| | `\u003cloc. name\u003e` | name of location from which timezone is identified | same as `site`'s examples |\n| | `\u003ctoml\u003e:\u003cloc. name\u003e` | user-defined location from which timezone is identified | same as `site`'s examples |\n\n### Output DataFrame\n\nThe output DataFrame contains az/el expressed in units of degrees and local sidereal time (LST) at `site` indexed by time in `view`:\n\n```python\n\u003e\u003e\u003e print(df)\n```\n```plaintext\n                                  az         el             lst\nAsia/Tokyo\n2020-01-01 00:00:00+09:00  94.820323  68.416756 17:07:59.405556\n2020-01-01 00:10:00+09:00  94.333979  70.709575 17:18:01.048298\n2020-01-01 00:20:00+09:00  93.856123  73.003864 17:28:02.691044\n2020-01-01 00:30:00+09:00  93.388695  75.299436 17:38:04.333786\n2020-01-01 00:40:00+09:00  92.935403  77.596109 17:48:05.976529\n...                              ...        ...             ...\n2020-01-01 23:20:00+09:00  96.711830  59.146249 16:31:49.389513\n2020-01-01 23:30:00+09:00  96.185941  61.431823 16:41:51.032256\n2020-01-01 23:40:00+09:00  95.664855  63.719668 16:51:52.674998\n2020-01-01 23:50:00+09:00  95.147951  66.009577 17:01:54.317740\n2020-01-02 00:00:00+09:00  94.634561  68.301349 17:11:55.960483\n\n[145 rows x 3 columns]\n```\n\n### Example\n\nHere is a sample script which will plot one-day elevation of the Sun and candidates of black hole shadow observations at ALMA AOS on Apr. 11th 2017 in UTC.\n\n```python\nimport azely\nimport matplotlib.pyplot as plt\nplt.style.use('seaborn-whitegrid')\n\nfig, ax = plt.subplots(figsize=(12, 4))\n\nsite = 'ALMA AOS'\ntime = 'Apr. 11th 2017'\nview = 'UTC'\n\nfor obj in ('Sun', 'Sgr A*', 'M87', 'M104', 'Cen A'):\n    df = azely.compute(obj, site, time, view)\n    df.el.plot(ax=ax, label=obj)\n\nax.set_title(f'site: {site}, view: {view}, time: {time}')\nax.set_ylabel('Elevation (deg)')\nax.set_ylim(0, 90)\nax.legend()\n```\n\n![multiple-objects.svg](https://raw.githubusercontent.com/astropenguin/azely/v0.7.0/docs/_static/multiple-objects.svg)\n\n## Advanced usage\n\nThis section describes advanced usage of azely by special DataFrame accessor and local [TOML] files.\nNote that azely will create a config directory, `$XDG_CONFIG_HOME/azely` (if the environment variable exists) or `~/.config/azely`, after importing `azely` for the first time.\n[TOML] files for configuration (`config.toml`) and cached information (`objects.toml`, `locations.toml`) will be automatically created in it.\n\n### Plotting in local sidereal time\n\nThe `compute()` function does not accept local sidereal time (LST) as `view` (i.e., `view='LST'`) because LST has no information on year and date.\nInstead an output DataFrame has `in_lst` property which provides az/el with a LST index converted from the original time index.\nFor example, the following code will plot elevation of an object in LST:\n\n```python\n\u003e\u003e\u003e df.in_lst.el.plot()\n```\n\nIn order to use LST values as an index of DataFrame, LST has pseudo dates which start from `1970-01-01`.\nPlease ignore them or hide them by using [Matplotlib] DateFormatter when you plot the result.\nHere is a sample script which has JST time axis at the bottom and LST axis at the top of a figure, respectively.\n\n```python\nimport matplotlib.dates as mdates\n\nfig, ax = plt.subplots(figsize=(12, 4))\ntwin = ax.twiny()\n\ndf = azely.compute('Sun', 'Tokyo', '2020-01-01')\ndf.el.plot(ax=ax, label=df.object.name)\ndf.in_lst.el.plot(ax=twin, alpha=0)\n\nax.set_ylabel(\"Elevation (deg)\")\nax.set_ylim(0, 90)\nax.legend()\n\nformatter = mdates.DateFormatter('%H:%M')\ntwin.xaxis.set_major_formatter(formatter)\nfig.autofmt_xdate(rotation=0)\n```\n\n![lst-axis.svg](https://raw.githubusercontent.com/astropenguin/azely/v0.7.0/docs/_static/lst-axis.svg)\n\n### User-defined information\n\nAzely offers to use user-defined information from a [TOML] file.\nHere is a sample TOML file (e.g., `user.toml`) which has custom object and location informaiton.\n\n```\n# user.toml\n\n[ASTE]\nname = \"ASTE Telescope\"\nlongitude = \"-67.70317915\"\nlatitude = \"-22.97163575\"\naltitude = \"0\"\n\n[GC]\nname = \"Galactic center\"\nframe = \"galactic\"\nlongitude = \"0deg\"\nlatitude = \"0deg\"\n```\n\nIf it is located in a current directory or in the azely's config directory, users can use the information like:\n\n```python\n\u003e\u003e\u003e df = azely.compute('user:GC', 'user:ASTE', '2020-01-01')\n```\n\n### Cached information\n\nObject and location information obtained from online services is cached to [TOML] files (`objects.toml`, `locations.toml`) in the azely's config directory with the same format as user-defined files.\nIf a query argument is given with `'!'` at the end of it, then the cached values are forcibly updated by a new acquisition.\nThis is useful, for example, when users want to update a current location:\n\n```python\n\u003e\u003e\u003e df = azely.compute('Sun', 'here!', '2020-01-01')\n```\n\n### Customizing default values\n\nUsers can modify default values of the `compute()` function by editing the azely's config [TOML] file (`config.toml`) in the azely's config directory like:\n\n```\n# config.toml\n\n[compute]\nsite = \"Tokyo\"\ntime = \"now\"\n```\n\nThen `compute('Sun')` becomes equivalent to `compute('Sun', 'Tokyo', 'now')`.\n\n\u003c!-- references --\u003e\n[Astropy]: https://astropy.org\n[Matplotlib]: https://matplotlib.org\n[pandas]: https://pandas.pydata.org\n[TOML]: https://toml.io\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastropenguin%2Fazely","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastropenguin%2Fazely","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastropenguin%2Fazely/lists"}