{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Adding shapes / graphic overlays\n", "\n", "There are two supported representations of exact shapes in `ipyaladin`:\n", " - the [Space Time Coordinates string (STCs)](https://ivoa.net/documents/STC-S/20130917/index.html)\n", " - the `astropy-regions` package objects\n", "\n", "If you're looking for MOCs, they have their own example in the repository: `5-Display_a_MOC.ipynb`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from ipyaladin import Aladin\n", "\n", "from astropy.coordinates import Angle, SkyCoord\n", "from astropy.io import fits\n", "from astropy.wcs import WCS\n", "import matplotlib.pyplot as plt\n", "from regions import (\n", " CircleSkyRegion,\n", " EllipseSkyRegion,\n", " LineSkyRegion,\n", " PolygonSkyRegion,\n", " RectangleSkyRegion,\n", " RegionVisual,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Add shapes from Space-Time Coordinates (STC)\n", "\n", "For now, `ipyaladin` supports a subset of STCs shapes and frames: the circles and polygons in frames `icrs`, `j2000`, and `fk5`.\n", "\n", "Operations between shapes (union, intersection, ...) are not supported, but lists of shapes in a same STC string do work." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "aladin = Aladin(target=\"M 51\", fov=1.2)\n", "aladin" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "aladin.add_graphic_overlay_from_stcs(\n", " \"\"\"Polygon ICRS 202.63748 47.24951 202.46382 47.32391 202.46379 47.32391 202.45459\n", " 47.32391 202.34527 47.20597 202.34527 47.20596 202.34529 47.19710 202.51870\n", " 47.12286 202.52789 47.12286 202.52791 47.12286 202.63746 47.24063 202.63749\n", " 47.24949\\nPolygon J2000 202.74977 47.36958 202.57592 47.44415 202.57585 47.44416\n", " 202.56666 47.44416 202.45683 47.32632 202.45683 47.31746 202.63051 47.24302\n", " 202.63970 47.24302 202.74978 47.36069 202.74982 47.36955\\nPolygon J2000 202.52540\n", " 47.12904 202.35192 47.20325 202.34273 47.20325 202.23391 47.08518 202.23395\n", " 47.07633 202.23398 47.07630 202.40715 47.00227 202.40721 47.00226 202.41640\n", " 47.00226 202.52539 47.12018\"\"\",\n", " color=\"red\",\n", ")\n", "aladin.add_graphic_overlay_from_stcs(\n", " \"Circle ICRS 202.4656816 +47.1999842 0.04\", color=\"#4488ee\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Add shapes from astropy-regions objects\n", "\n", "The ipyaladin widget can also represent the following [`astropy-regions`](https://astropy-regions.readthedocs.io) shapes:\n", "- `CircleSkyRegion`,\n", "- `EllipseSkyRegion`,\n", "- `LineSkyRegion`,\n", "- `PolygonSkyRegion`,\n", "- `RectangleSkyRegion`.\n", "\n", "Let's create one of each:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "center = SkyCoord.from_name(\"M31\")\n", "circle = CircleSkyRegion(\n", " center=center, radius=Angle(0.5, \"deg\"), visual={\"edgecolor\": \"yellow\"}\n", ")\n", "ellipse = EllipseSkyRegion(\n", " center=center,\n", " height=Angle(0.5, \"deg\"),\n", " width=Angle(1, \"deg\"),\n", " angle=Angle(45, \"deg\"),\n", " visual=RegionVisual(edgecolor=\"red\"),\n", ")\n", "line = LineSkyRegion(\n", " start=center,\n", " end=center.directional_offset_by(Angle(0, \"deg\"), Angle(0.5, \"deg\")),\n", " visual=RegionVisual(edgecolor=\"green\"),\n", ")\n", "polygon = PolygonSkyRegion(\n", " vertices=SkyCoord(\n", " [\n", " center.directional_offset_by(Angle(0, \"deg\"), Angle(0.5, \"deg\")),\n", " center.directional_offset_by(Angle(90, \"deg\"), Angle(0.5, \"deg\")),\n", " center.directional_offset_by(Angle(-90, \"deg\"), Angle(0.5, \"deg\")),\n", " ],\n", " frame=\"icrs\",\n", " unit=\"deg\",\n", " ),\n", " visual={\"edgecolor\": \"blue\"},\n", ")\n", "rectangle = RectangleSkyRegion(\n", " center=center,\n", " width=Angle(1, \"deg\"),\n", " height=Angle(1, \"deg\"),\n", " angle=Angle(45, \"deg\"),\n", " visual=RegionVisual(color=\"purple\"),\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And plot them first with matplotlib" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "hdu_list = fits.open(\"images/m31.fits\")\n", "hdu_list.info()\n", "wcs = WCS(hdu_list[0].header).dropaxis(2)\n", "\n", "plt.subplot(projection=wcs)\n", "plt.imshow(hdu_list[0].data[0, :, :], cmap=\"gray\")\n", "\n", "circle.to_pixel(wcs).plot(ax=plt.gca())\n", "ellipse.to_pixel(wcs).plot(ax=plt.gca())\n", "line.to_pixel(wcs).plot(ax=plt.gca())\n", "polygon.to_pixel(wcs).plot(ax=plt.gca())\n", "rectangle.to_pixel(wcs).plot(ax=plt.gca())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now in ipyaladin" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "aladin = Aladin(target=\"m31\", fov=10)\n", "aladin" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "aladin.add_graphic_overlay_from_region([circle, ellipse, line, polygon, rectangle])" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.8" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": false, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": false, "toc_window_display": false }, "vscode": { "interpreter": { "hash": "85bb43f988bdbdc027a50b6d744a62eda8a76617af1f4f9b115d38242716dbac" } } }, "nbformat": 4, "nbformat_minor": 4 }