mirror of
https://github.com/AllenDowney/AstronomicalData.git
synced 2026-01-03 16:17:06 -08:00
1821 lines
98 KiB
HTML
1821 lines
98 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Photometry — Astronomical Data in Python</title>
|
||
|
||
<link rel="stylesheet" href="_static/css/index.d431a4ee1c1efae0e38bdfebc22debff.css">
|
||
|
||
|
||
<link rel="stylesheet"
|
||
href="_static/vendor/fontawesome/5.13.0/css/all.min.css">
|
||
<link rel="preload" as="font" type="font/woff2" crossorigin
|
||
href="_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
|
||
<link rel="preload" as="font" type="font/woff2" crossorigin
|
||
href="_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
|
||
|
||
|
||
|
||
<link rel="stylesheet"
|
||
href="_static/vendor/open-sans_all/1.44.1/index.css">
|
||
<link rel="stylesheet"
|
||
href="_static/vendor/lato_latin-ext/1.44.1/index.css">
|
||
|
||
|
||
<link rel="stylesheet" href="_static/sphinx-book-theme.bfb7730f9caf2ec0b46a44615585038c.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||
<link rel="stylesheet" type="text/css" href="_static/togglebutton.css" />
|
||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||
<link rel="stylesheet" type="text/css" href="_static/mystnb.css" />
|
||
<link rel="stylesheet" type="text/css" href="_static/sphinx-thebe.css" />
|
||
<link rel="stylesheet" type="text/css" href="_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css" />
|
||
<link rel="stylesheet" type="text/css" href="_static/panels-variables.06eb56fa6e07937060861dad626602ad.css" />
|
||
|
||
<link rel="preload" as="script" href="_static/js/index.30270b6e4c972e43c488.js">
|
||
|
||
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
|
||
<script src="_static/jquery.js"></script>
|
||
<script src="_static/underscore.js"></script>
|
||
<script src="_static/doctools.js"></script>
|
||
<script src="_static/language_data.js"></script>
|
||
<script src="_static/togglebutton.js"></script>
|
||
<script src="_static/clipboard.min.js"></script>
|
||
<script src="_static/copybutton.js"></script>
|
||
<script >var togglebuttonSelector = '.toggle, .admonition.dropdown, .tag_hide_input div.cell_input, .tag_hide-input div.cell_input, .tag_hide_output div.cell_output, .tag_hide-output div.cell_output, .tag_hide_cell.cell, .tag_hide-cell.cell';</script>
|
||
<script src="_static/sphinx-book-theme.be0a4a0c39cd630af62a2fcf693f3f06.js"></script>
|
||
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
|
||
<script async="async" src="https://unpkg.com/thebelab@latest/lib/index.js"></script>
|
||
<script >
|
||
const thebe_selector = ".thebe"
|
||
const thebe_selector_input = "pre"
|
||
const thebe_selector_output = ".output"
|
||
</script>
|
||
<script async="async" src="_static/sphinx-thebe.js"></script>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="next" title="Visualization" href="07_plot.html" />
|
||
<link rel="prev" title="Joining Tables" href="05_join.html" />
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta name="docsearch:language" content="en" />
|
||
|
||
|
||
|
||
</head>
|
||
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
|
||
|
||
|
||
<div class="container-xl">
|
||
<div class="row">
|
||
|
||
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
|
||
|
||
<div class="navbar-brand-box">
|
||
<a class="navbar-brand text-wrap" href="index.html">
|
||
|
||
|
||
<h1 class="site-logo" id="site-title">Astronomical Data in Python</h1>
|
||
|
||
</a>
|
||
</div>
|
||
|
||
<form class="bd-search d-flex align-items-center" action="search.html" method="get">
|
||
<i class="icon fas fa-search"></i>
|
||
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search this book..." aria-label="Search this book..." autocomplete="off" >
|
||
</form>
|
||
|
||
<nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
|
||
<ul class="nav sidenav_l1">
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="README.html">
|
||
Astronomical Data in Python
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<ul class="current nav sidenav_l1">
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="01_query.html">
|
||
Queries
|
||
</a>
|
||
</li>
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="02_coords.html">
|
||
Coordinates and units
|
||
</a>
|
||
</li>
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="03_motion.html">
|
||
Proper Motion
|
||
</a>
|
||
</li>
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="04_select.html">
|
||
Transformation and Selection
|
||
</a>
|
||
</li>
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="05_join.html">
|
||
Joining Tables
|
||
</a>
|
||
</li>
|
||
<li class="toctree-l1 current active">
|
||
<a class="current reference internal" href="#">
|
||
Photometry
|
||
</a>
|
||
</li>
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="07_plot.html">
|
||
Visualization
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
<!-- To handle the deprecated key -->
|
||
|
||
<div class="navbar_extra_footer">
|
||
Powered by <a href="https://jupyterbook.org">Jupyter Book</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
|
||
|
||
<div class="row topbar fixed-top container-xl">
|
||
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show">
|
||
</div>
|
||
<div class="col pl-2 topbar-main">
|
||
|
||
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
|
||
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
|
||
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
|
||
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
|
||
<i class="fas fa-bars"></i>
|
||
<i class="fas fa-arrow-left"></i>
|
||
<i class="fas fa-arrow-up"></i>
|
||
</button>
|
||
|
||
<div class="dropdown-buttons-trigger">
|
||
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
|
||
class="fas fa-download"></i></button>
|
||
|
||
|
||
<div class="dropdown-buttons">
|
||
<!-- ipynb file if we had a myst markdown file -->
|
||
|
||
<!-- Download raw file -->
|
||
<a class="dropdown-buttons" href="_sources/06_photo.ipynb"><button type="button"
|
||
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
|
||
data-placement="left">.ipynb</button></a>
|
||
<!-- Download PDF via print -->
|
||
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
|
||
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
|
||
</div>
|
||
|
||
</div>
|
||
<!-- Source interaction buttons -->
|
||
|
||
<div class="dropdown-buttons-trigger">
|
||
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
|
||
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
|
||
<div class="dropdown-buttons sourcebuttons">
|
||
<a class="repository-button"
|
||
href="https://github.com/AllenDowney/AstronomicalData"><button type="button" class="btn btn-secondary topbarbtn"
|
||
data-toggle="tooltip" data-placement="left" title="Source repository"><i
|
||
class="fab fa-github"></i>repository</button></a>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- Full screen (wrap in <a> to have style consistency -->
|
||
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
|
||
data-placement="bottom" onclick="toggleFullScreen()" title="Fullscreen mode"><i
|
||
class="fas fa-expand"></i></button></a>
|
||
|
||
<!-- Launch buttons -->
|
||
|
||
<div class="dropdown-buttons-trigger">
|
||
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
|
||
aria-label="Launch interactive content"><i class="fas fa-rocket"></i></button>
|
||
<div class="dropdown-buttons">
|
||
|
||
<a class="binder-button" href="https://mybinder.org/v2/gh/AllenDowney/AstronomicalData/master?urlpath=tree/06_photo.ipynb"><button type="button"
|
||
class="btn btn-secondary topbarbtn" title="Launch Binder" data-toggle="tooltip"
|
||
data-placement="left"><img class="binder-button-logo"
|
||
src="_static/images/logo_binder.svg"
|
||
alt="Interact on binder">Binder</button></a>
|
||
|
||
|
||
|
||
<a class="colab-button" href="https://colab.research.google.com/github/AllenDowney/AstronomicalData/blob/master/06_photo.ipynb"><button type="button" class="btn btn-secondary topbarbtn"
|
||
title="Launch Colab" data-toggle="tooltip" data-placement="left"><img class="colab-button-logo"
|
||
src="_static/images/logo_colab.png"
|
||
alt="Interact on Colab">Colab</button></a>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Table of contents -->
|
||
<div class="d-none d-md-block col-md-2 bd-toc show">
|
||
|
||
<div class="tocsection onthispage pt-5 pb-3">
|
||
<i class="fas fa-list"></i> Contents
|
||
</div>
|
||
<nav id="bd-toc-nav">
|
||
<ul class="nav section-nav flex-column">
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#outline">
|
||
Outline
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#reload-the-data">
|
||
Reload the data
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#plotting-photometry-data">
|
||
Plotting photometry data
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#isochrone">
|
||
Isochrone
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#making-a-polygon">
|
||
Making a polygon
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#which-points-are-in-the-polygon">
|
||
Which points are in the polygon?
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#reloading-the-data">
|
||
Reloading the data
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#merging-photometry-data">
|
||
Merging photometry data
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#missing-data">
|
||
Missing data
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#selecting-based-on-photometry">
|
||
Selecting based on photometry
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#write-the-data">
|
||
Write the data
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#save-the-polygon">
|
||
Save the polygon
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#summary">
|
||
Summary
|
||
</a>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry">
|
||
<a class="reference internal nav-link" href="#best-practices">
|
||
Best practices
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
</div>
|
||
</div>
|
||
<div id="main-content" class="row">
|
||
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
|
||
|
||
<div>
|
||
|
||
<div class="section" id="photometry">
|
||
<h1>Photometry<a class="headerlink" href="#photometry" title="Permalink to this headline">¶</a></h1>
|
||
<p>This is the sixth in a series of notebooks related to astronomy data.</p>
|
||
<p>As a continuing example, we will replicate part of the analysis in a recent paper, “<a class="reference external" href="https://arxiv.org/abs/1805.00425">Off the beaten path: Gaia reveals GD-1 stars outside of the main stream</a>” by Adrian M. Price-Whelan and Ana Bonaca.</p>
|
||
<p>In the previous lesson we downloaded photometry data from Pan-STARRS, which is available from the same server we’ve been using to get Gaia data.</p>
|
||
<p>The next step in the analysis is to select candidate stars based on the photometry data.<br />
|
||
The following figure from the paper is a color-magnitude diagram showing the stars we previously selected based on proper motion:</p>
|
||
<a class="reference internal image-reference" href="https://github.com/datacarpentry/astronomy-python/raw/gh-pages/fig/gd1-3.png"><img alt="https://github.com/datacarpentry/astronomy-python/raw/gh-pages/fig/gd1-3.png" src="https://github.com/datacarpentry/astronomy-python/raw/gh-pages/fig/gd1-3.png" style="width: 300px;" /></a>
|
||
<p>In red is a theoretical isochrone, showing where we expect the stars in GD-1 to fall based on the metallicity and age of their original globular cluster.</p>
|
||
<p>By selecting stars in the shaded area, we can further distinguish the main sequence of GD-1 from mostly younger background stars.</p>
|
||
<div class="section" id="outline">
|
||
<h2>Outline<a class="headerlink" href="#outline" title="Permalink to this headline">¶</a></h2>
|
||
<p>Here are the steps in this notebook:</p>
|
||
<ol class="simple">
|
||
<li><p>We’ll reload the data from the previous notebook and make a color-magnitude diagram.</p></li>
|
||
<li><p>We’ll use an isochrone computed by MIST to specify a polygonal region in the color-magnitude diagram and select the stars inside it.</p></li>
|
||
<li><p>Then we’ll merge the photometry data with the list of candidate stars, storing the result in a Pandas <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code>.</p></li>
|
||
</ol>
|
||
<p>After completing this lesson, you should be able to</p>
|
||
<ul class="simple">
|
||
<li><p>Use Matplotlib to specify a <code class="docutils literal notranslate"><span class="pre">Polygon</span></code> and determine which points fall inside it.</p></li>
|
||
<li><p>Use Pandas to merge data from multiple <code class="docutils literal notranslate"><span class="pre">DataFrames</span></code>, much like a database <code class="docutils literal notranslate"><span class="pre">JOIN</span></code> operation.</p></li>
|
||
</ul>
|
||
</div>
|
||
<div class="section" id="reload-the-data">
|
||
<h2>Reload the data<a class="headerlink" href="#reload-the-data" title="Permalink to this headline">¶</a></h2>
|
||
<p>The following cell downloads the photometry data we created in the previous notebook.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
|
||
<span class="kn">from</span> <span class="nn">wget</span> <span class="kn">import</span> <span class="n">download</span>
|
||
|
||
<span class="n">filename</span> <span class="o">=</span> <span class="s1">'gd1_photo.fits'</span>
|
||
<span class="n">filepath</span> <span class="o">=</span> <span class="s1">'https://github.com/AllenDowney/AstronomicalData/raw/main/data/'</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">download</span><span class="p">(</span><span class="n">filepath</span><span class="o">+</span><span class="n">filename</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can read the data back into an Astropy <code class="docutils literal notranslate"><span class="pre">Table</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">astropy.table</span> <span class="kn">import</span> <span class="n">Table</span>
|
||
|
||
<span class="n">photo_table</span> <span class="o">=</span> <span class="n">Table</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="plotting-photometry-data">
|
||
<h2>Plotting photometry data<a class="headerlink" href="#plotting-photometry-data" title="Permalink to this headline">¶</a></h2>
|
||
<p>Now that we have photometry data from Pan-STARRS, we can replicate the <a class="reference external" href="https://en.wikipedia.org/wiki/Galaxy_color%E2%80%93magnitude_diagram">color-magnitude diagram</a> from the original paper:</p>
|
||
<a class="reference internal image-reference" href="https://github.com/datacarpentry/astronomy-python/raw/gh-pages/fig/gd1-3.png"><img alt="https://github.com/datacarpentry/astronomy-python/raw/gh-pages/fig/gd1-3.png" src="https://github.com/datacarpentry/astronomy-python/raw/gh-pages/fig/gd1-3.png" style="width: 300px;" /></a>
|
||
<p>The y-axis shows the apparent magnitude of each source with the <a class="reference external" href="https://en.wikipedia.org/wiki/Photometric_system">g filter</a>.</p>
|
||
<p>The x-axis shows the difference in apparent magnitude between the g and i filters, which indicates color.</p>
|
||
<p>Stars with lower values of (g-i) are brighter in g-band than in i-band, compared to other stars, which means they are bluer.</p>
|
||
<p>Stars in the lower-left quadrant of this diagram are less bright and less metallic than the others, which means they are <a class="reference external" href="http://spiff.rit.edu/classes/ladder/lectures/ordinary_stars/ordinary.html">likely to be older</a>.</p>
|
||
<p>Since we expect the stars in GD-1 to be older than the background stars, the stars in the lower-left are more likely to be in GD-1.</p>
|
||
<p>The following function takes a table containing photometry data and draws a color-magnitude diagram.
|
||
The input can be an Astropy <code class="docutils literal notranslate"><span class="pre">Table</span></code> or Pandas <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code>, as long as it has columns named <code class="docutils literal notranslate"><span class="pre">g_mean_psf_mag</span></code> and <code class="docutils literal notranslate"><span class="pre">i_mean_psf_mag</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
|
||
|
||
<span class="k">def</span> <span class="nf">plot_cmd</span><span class="p">(</span><span class="n">table</span><span class="p">):</span>
|
||
<span class="sd">"""Plot a color magnitude diagram.</span>
|
||
<span class="sd"> </span>
|
||
<span class="sd"> table: Table or DataFrame with photometry data</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">table</span><span class="p">[</span><span class="s1">'g_mean_psf_mag'</span><span class="p">]</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">table</span><span class="p">[</span><span class="s1">'g_mean_psf_mag'</span><span class="p">]</span> <span class="o">-</span> <span class="n">table</span><span class="p">[</span><span class="s1">'i_mean_psf_mag'</span><span class="p">]</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'ko'</span><span class="p">,</span> <span class="n">markersize</span><span class="o">=</span><span class="mf">0.3</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.3</span><span class="p">)</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">xlim</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mf">1.5</span><span class="p">])</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">ylim</span><span class="p">([</span><span class="mi">14</span><span class="p">,</span> <span class="mi">22</span><span class="p">])</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">gca</span><span class="p">()</span><span class="o">.</span><span class="n">invert_yaxis</span><span class="p">()</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">'$g_0$'</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">'$(g-i)_0$'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">plot_cmd</span></code> uses a new function, <code class="docutils literal notranslate"><span class="pre">invert_yaxis</span></code>, to invert the <code class="docutils literal notranslate"><span class="pre">y</span></code> axis, which is conventional when plotting magnitudes, since lower magnitude indicates higher brightness.</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">invert_yaxis</span></code> is a little different from the other functions we’ve used. You can’t call it like this:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">plt</span><span class="o">.</span><span class="n">invert_yaxis</span><span class="p">()</span> <span class="c1"># doesn't work</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>You have to call it like this:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">plt</span><span class="o">.</span><span class="n">gca</span><span class="p">()</span><span class="o">.</span><span class="n">invert_yaxis</span><span class="p">()</span> <span class="c1"># works</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">gca</span></code> stands for “get current axis”. It returns an object that represents the axes of the current figure, and that object provides <code class="docutils literal notranslate"><span class="pre">invert_yaxis</span></code>.</p>
|
||
<p><strong>In case anyone asks:</strong> The most likely reason for this inconsistency in the interface is that <code class="docutils literal notranslate"><span class="pre">invert_yaxis</span></code> is a lesser-used function, so it’s not made available at the top level of the interface.</p>
|
||
<p>Here’s what the results look like.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">plot_cmd</span><span class="p">(</span><span class="n">photo_table</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_14_0.png" src="_images/06_photo_14_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>Our figure does not look exactly like the one in the paper because we are working with a smaller region of the sky, so we don’t have as many stars. But we can see an overdense region in the lower left that contains stars with the photometry we expect for GD-1.</p>
|
||
<p>In the next section we’ll use an isochrone to specify a polygon that contains this overdense regioin.</p>
|
||
</div>
|
||
<div class="section" id="isochrone">
|
||
<h2>Isochrone<a class="headerlink" href="#isochrone" title="Permalink to this headline">¶</a></h2>
|
||
<p>Based on our best estimates for the ages of the stars in GD-1 and their metallicity, we can compute a <a class="reference external" href="https://en.wikipedia.org/wiki/Stellar_isochrone">stellar isochrone</a> that predicts the relationship between their magnitude and color.</p>
|
||
<p>In fact, we can use <a class="reference external" href="http://waps.cfa.harvard.edu/MIST/">MESA Isochrones & Stellar Tracks</a> (MIST) to compute it for us.</p>
|
||
<p>Using the <a class="reference external" href="http://waps.cfa.harvard.edu/MIST/interp_isos.html">MIST Version 1.2 web interface</a>, we computed an isochrone with the following parameters:</p>
|
||
<ul class="simple">
|
||
<li><p>Rotation initial v/v_crit = 0.4</p></li>
|
||
<li><p>Single age, linear scale = 12e9</p></li>
|
||
<li><p>Composition [Fe/H] = -1.35</p></li>
|
||
<li><p>Synthetic Photometry, PanStarrs</p></li>
|
||
<li><p>Extinction av = 0</p></li>
|
||
</ul>
|
||
<p>The following cell downloads the results:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
|
||
<span class="kn">from</span> <span class="nn">wget</span> <span class="kn">import</span> <span class="n">download</span>
|
||
|
||
<span class="n">filename</span> <span class="o">=</span> <span class="s1">'MIST_iso_5fd2532653c27.iso.cmd'</span>
|
||
<span class="n">filepath</span> <span class="o">=</span> <span class="s1">'https://github.com/AllenDowney/AstronomicalData/raw/main/data/'</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">download</span><span class="p">(</span><span class="n">filepath</span><span class="o">+</span><span class="n">filename</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>To read this file we’ll download a Python module <a class="reference external" href="https://github.com/jieunchoi/MIST_codes">from this repository</a>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
|
||
<span class="kn">from</span> <span class="nn">wget</span> <span class="kn">import</span> <span class="n">download</span>
|
||
|
||
<span class="n">filename</span> <span class="o">=</span> <span class="s1">'read_mist_models.py'</span>
|
||
<span class="n">filepath</span> <span class="o">=</span> <span class="s1">'https://github.com/jieunchoi/MIST_codes/raw/master/scripts/'</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">download</span><span class="p">(</span><span class="n">filepath</span><span class="o">+</span><span class="n">filename</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can read the file:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">read_mist_models</span>
|
||
|
||
<span class="n">filename</span> <span class="o">=</span> <span class="s1">'MIST_iso_5fd2532653c27.iso.cmd'</span>
|
||
<span class="n">iso</span> <span class="o">=</span> <span class="n">read_mist_models</span><span class="o">.</span><span class="n">ISOCMD</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>Reading in: MIST_iso_5fd2532653c27.iso.cmd
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The result is an <code class="docutils literal notranslate"><span class="pre">ISOCMD</span></code> object.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">type</span><span class="p">(</span><span class="n">iso</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>read_mist_models.ISOCMD
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>It contains a list of arrays, one for each isochrone.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">type</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">isocmds</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>list
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We only got one isochrone.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">isocmds</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>1
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>So we can select it like this:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">iso_array</span> <span class="o">=</span> <span class="n">iso</span><span class="o">.</span><span class="n">isocmds</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>It’s a NumPy array:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">type</span><span class="p">(</span><span class="n">iso_array</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>numpy.ndarray
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>But it’s an unusual NumPy array, because it contains names for the columns.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">iso_array</span><span class="o">.</span><span class="n">dtype</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>dtype([('EEP', '<i4'), ('isochrone_age_yr', '<f8'), ('initial_mass', '<f8'), ('star_mass', '<f8'), ('log_Teff', '<f8'), ('log_g', '<f8'), ('log_L', '<f8'), ('[Fe/H]_init', '<f8'), ('[Fe/H]', '<f8'), ('PS_g', '<f8'), ('PS_r', '<f8'), ('PS_i', '<f8'), ('PS_z', '<f8'), ('PS_y', '<f8'), ('PS_w', '<f8'), ('PS_open', '<f8'), ('phase', '<f8')])
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Which means we can select columns using the bracket operator:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">iso_array</span><span class="p">[</span><span class="s1">'phase'</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>array([0., 0., 0., ..., 6., 6., 6.])
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We can use <code class="docutils literal notranslate"><span class="pre">phase</span></code> to select the part of the isochrone for stars in the main sequence and red giant phases.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">phase_mask</span> <span class="o">=</span> <span class="p">(</span><span class="n">iso_array</span><span class="p">[</span><span class="s1">'phase'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&</span> <span class="p">(</span><span class="n">iso_array</span><span class="p">[</span><span class="s1">'phase'</span><span class="p">]</span> <span class="o"><</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="n">phase_mask</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>354
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">main_sequence</span> <span class="o">=</span> <span class="n">iso_array</span><span class="p">[</span><span class="n">phase_mask</span><span class="p">]</span>
|
||
<span class="nb">len</span><span class="p">(</span><span class="n">main_sequence</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>354
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The other two columns we’ll use are <code class="docutils literal notranslate"><span class="pre">PS_g</span></code> and <code class="docutils literal notranslate"><span class="pre">PS_i</span></code>, which contain simulated photometry data for stars with the given age and metallicity, based on a model of the Pan-STARRS sensors.</p>
|
||
<p>We’ll use these columns to superimpose the isochrone on the color-magnitude diagram, but first we have to use a <a class="reference external" href="https://en.wikipedia.org/wiki/Distance_modulus">distance modulus</a> to scale the isochrone based on the estimated distance of GD-1.</p>
|
||
<p>We can use the <code class="docutils literal notranslate"><span class="pre">Distance</span></code> object from Astropy to compute the distance modulus.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">astropy.coordinates</span> <span class="k">as</span> <span class="nn">coord</span>
|
||
<span class="kn">import</span> <span class="nn">astropy.units</span> <span class="k">as</span> <span class="nn">u</span>
|
||
|
||
<span class="n">distance</span> <span class="o">=</span> <span class="mf">7.8</span> <span class="o">*</span> <span class="n">u</span><span class="o">.</span><span class="n">kpc</span>
|
||
<span class="n">distmod</span> <span class="o">=</span> <span class="n">coord</span><span class="o">.</span><span class="n">Distance</span><span class="p">(</span><span class="n">distance</span><span class="p">)</span><span class="o">.</span><span class="n">distmod</span><span class="o">.</span><span class="n">value</span>
|
||
<span class="n">distmod</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>14.4604730134524
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can compute the scaled magnitude and color of the isochrone.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">main_sequence</span><span class="p">[</span><span class="s1">'PS_g'</span><span class="p">]</span> <span class="o">+</span> <span class="n">distmod</span>
|
||
<span class="n">gi</span> <span class="o">=</span> <span class="n">main_sequence</span><span class="p">[</span><span class="s1">'PS_g'</span><span class="p">]</span> <span class="o">-</span> <span class="n">main_sequence</span><span class="p">[</span><span class="s1">'PS_i'</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>To make this data easier to work with, we’ll put it in a Pandas <code class="docutils literal notranslate"><span class="pre">Series</span></code> with that contains <code class="docutils literal notranslate"><span class="pre">gi</span></code> as the index and <code class="docutils literal notranslate"><span class="pre">g</span></code> as the values.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
|
||
<span class="n">iso_series</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="n">gi</span><span class="p">)</span>
|
||
<span class="n">iso_series</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>2.195021 28.294743
|
||
2.166076 28.189718
|
||
2.129312 28.051761
|
||
2.093721 27.916194
|
||
2.058585 27.780024
|
||
dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can plot it on the color-magnitude diagram like this.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">plot_cmd</span><span class="p">(</span><span class="n">photo_table</span><span class="p">)</span>
|
||
<span class="n">iso_series</span><span class="o">.</span><span class="n">plot</span><span class="p">();</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_46_0.png" src="_images/06_photo_46_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>The theoretical isochrone passes through the overdense region where we expect to find stars in GD-1.</p>
|
||
<p>Let’s save this result so we can reload it later without repeating the steps in this section.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">filename</span> <span class="o">=</span> <span class="s1">'gd1_isochrone.hdf5'</span>
|
||
|
||
<span class="n">iso_series</span><span class="o">.</span><span class="n">to_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'iso_series'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="making-a-polygon">
|
||
<h2>Making a polygon<a class="headerlink" href="#making-a-polygon" title="Permalink to this headline">¶</a></h2>
|
||
<p>The following cell downloads the isochrone series we made in the previous section, if necessary.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
|
||
<span class="kn">from</span> <span class="nn">wget</span> <span class="kn">import</span> <span class="n">download</span>
|
||
|
||
<span class="n">filename</span> <span class="o">=</span> <span class="s1">'gd1_isochrone.hdf5'</span>
|
||
<span class="n">filepath</span> <span class="o">=</span> <span class="s1">'https://github.com/AllenDowney/AstronomicalData/raw/main/data/'</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">download</span><span class="p">(</span><span class="n">filepath</span><span class="o">+</span><span class="n">filename</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can read the isochrone back in.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">iso_series</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'iso_series'</span><span class="p">)</span>
|
||
<span class="n">iso_series</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>2.195021 28.294743
|
||
2.166076 28.189718
|
||
2.129312 28.051761
|
||
2.093721 27.916194
|
||
2.058585 27.780024
|
||
dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>To select the stars in the overdense region of the color-magnitude diagram, we want to stretch the isochrone into a polygon.</p>
|
||
<p>We’ll use the following formulas to compute the left and right sides of the polygons.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">iso_series</span><span class="o">.</span><span class="n">to_numpy</span><span class="p">()</span>
|
||
<span class="n">gi</span> <span class="o">=</span> <span class="n">iso_series</span><span class="o">.</span><span class="n">index</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">left_gi</span> <span class="o">=</span> <span class="n">gi</span> <span class="o">-</span> <span class="mf">0.4</span> <span class="o">*</span> <span class="p">(</span><span class="n">g</span><span class="o">/</span><span class="mi">28</span><span class="p">)</span><span class="o">**</span><span class="mi">5</span>
|
||
<span class="n">right_gi</span> <span class="o">=</span> <span class="n">gi</span> <span class="o">+</span> <span class="mf">0.7</span> <span class="o">*</span> <span class="p">(</span><span class="n">g</span><span class="o">/</span><span class="mi">28</span><span class="p">)</span><span class="o">**</span><span class="mi">5</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>To explain the terms:</p>
|
||
<ul class="simple">
|
||
<li><p>We divide magnitudes by 28 to normalize them onto the range from 0 to 1.</p></li>
|
||
<li><p>Raising the normalized magnitudes to the 5th power [DOES WHAT?]</p></li>
|
||
<li><p>Then we add and subtract the result from <code class="docutils literal notranslate"><span class="pre">gi</span></code> to shift the isochrone left and right. The factors 0.4 and 0.7 were chosen by eye to enclose the overdense region.</p></li>
|
||
</ul>
|
||
<p>To make the shifted isochrones easier to work with, we’ll put them in a Pandas <code class="docutils literal notranslate"><span class="pre">Series</span></code> with that contains both <code class="docutils literal notranslate"><span class="pre">g</span></code> and the scaled values of <code class="docutils literal notranslate"><span class="pre">gi</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
|
||
<span class="n">left_series</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="n">left_gi</span><span class="p">)</span>
|
||
<span class="n">left_series</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>1.773520 28.294743
|
||
1.752340 28.189718
|
||
1.725601 28.051761
|
||
1.699671 27.916194
|
||
1.674053 27.780024
|
||
dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">right_series</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="n">right_gi</span><span class="p">)</span>
|
||
<span class="n">right_series</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>2.932648 28.294743
|
||
2.890114 28.189718
|
||
2.835806 28.051761
|
||
2.783308 27.916194
|
||
2.731517 27.780024
|
||
dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can plot them on the color-magnitude diagram like this.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">plot_cmd</span><span class="p">(</span><span class="n">photo_table</span><span class="p">)</span>
|
||
<span class="n">left_series</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
|
||
<span class="n">right_series</span><span class="o">.</span><span class="n">plot</span><span class="p">();</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_61_0.png" src="_images/06_photo_61_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>It looks like the scaled isochrones bound the overdense area well, but they also include stars with magnitudes higher than we expect for stars in GD-1, so we’ll use another mask to limit the range of <code class="docutils literal notranslate"><span class="pre">g</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">g_mask</span> <span class="o">=</span> <span class="p">(</span><span class="n">g</span> <span class="o">></span> <span class="mf">18.0</span><span class="p">)</span> <span class="o">&</span> <span class="p">(</span><span class="n">g</span> <span class="o"><</span> <span class="mf">21.5</span><span class="p">)</span>
|
||
<span class="n">g_mask</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>117
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">left</span> <span class="o">=</span> <span class="n">left_series</span><span class="p">[</span><span class="n">g_mask</span><span class="p">]</span>
|
||
<span class="n">right</span> <span class="o">=</span> <span class="n">right_series</span><span class="p">[</span><span class="n">g_mask</span><span class="p">]</span>
|
||
|
||
<span class="nb">len</span><span class="p">(</span><span class="n">left</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">right</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>(117, 117)
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Here’s what they look like:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">plot_cmd</span><span class="p">(</span><span class="n">photo_table</span><span class="p">)</span>
|
||
<span class="n">left</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
|
||
<span class="n">right</span><span class="o">.</span><span class="n">plot</span><span class="p">();</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_66_0.png" src="_images/06_photo_66_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>Now we want to assemble the two halves into a polygon. We can use <code class="docutils literal notranslate"><span class="pre">append</span></code> to make a new <code class="docutils literal notranslate"><span class="pre">Series</span></code> that contains both halves.</p>
|
||
<p>And we’ll use the slice <code class="docutils literal notranslate"><span class="pre">[::-1]</span></code> to reverse the elements of <code class="docutils literal notranslate"><span class="pre">right</span></code> so the result forms a loop. <a class="reference external" href="https://stackoverflow.com/questions/5876998/reversing-a-list-using-slice-notation">See here for an explanation of this idiom</a>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">loop</span> <span class="o">=</span> <span class="n">left</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">right</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
||
<span class="n">loop</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>0.587571 21.411746
|
||
0.567801 21.322466
|
||
0.548134 21.233380
|
||
0.528693 21.144427
|
||
0.509300 21.054549
|
||
dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The following lines add metadata by assigning names to the values and the index in <code class="docutils literal notranslate"><span class="pre">loop</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">loop</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'g'</span>
|
||
<span class="n">loop</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'gi'</span>
|
||
<span class="n">loop</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>gi
|
||
0.587571 21.411746
|
||
0.567801 21.322466
|
||
0.548134 21.233380
|
||
0.528693 21.144427
|
||
0.509300 21.054549
|
||
Name: g, dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>And here’s what it looks like</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">loop</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
|
||
<span class="n">plot_cmd</span><span class="p">(</span><span class="n">photo_table</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_72_0.png" src="_images/06_photo_72_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>Next we’ll use this polygon to identify stars in the overdense region.</p>
|
||
</div>
|
||
<div class="section" id="which-points-are-in-the-polygon">
|
||
<h2>Which points are in the polygon?<a class="headerlink" href="#which-points-are-in-the-polygon" title="Permalink to this headline">¶</a></h2>
|
||
<p>Matplotlib provides a <code class="docutils literal notranslate"><span class="pre">Path</span></code> object that we can use to check which points fall in the polygon we just constructed.</p>
|
||
<p>To make a <code class="docutils literal notranslate"><span class="pre">Path</span></code>, we need a list of coordinates in the form of an array with two columns.</p>
|
||
<p>Currently <code class="docutils literal notranslate"><span class="pre">loop</span></code> is a <code class="docutils literal notranslate"><span class="pre">Series</span></code> with the values of <code class="docutils literal notranslate"><span class="pre">gi</span></code> in the index:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">loop</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>gi
|
||
0.587571 21.411746
|
||
0.567801 21.322466
|
||
0.548134 21.233380
|
||
0.528693 21.144427
|
||
0.509300 21.054549
|
||
Name: g, dtype: float64
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We can move them out of the index into a column using <code class="docutils literal notranslate"><span class="pre">reset_index</span></code>:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">loop_df</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">reset_index</span><span class="p">()</span>
|
||
<span class="n">loop_df</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_html"><div>
|
||
<style scoped>
|
||
.dataframe tbody tr th:only-of-type {
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.dataframe tbody tr th {
|
||
vertical-align: top;
|
||
}
|
||
|
||
.dataframe thead th {
|
||
text-align: right;
|
||
}
|
||
</style>
|
||
<table border="1" class="dataframe">
|
||
<thead>
|
||
<tr style="text-align: right;">
|
||
<th></th>
|
||
<th>gi</th>
|
||
<th>g</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<th>0</th>
|
||
<td>0.587571</td>
|
||
<td>21.411746</td>
|
||
</tr>
|
||
<tr>
|
||
<th>1</th>
|
||
<td>0.567801</td>
|
||
<td>21.322466</td>
|
||
</tr>
|
||
<tr>
|
||
<th>2</th>
|
||
<td>0.548134</td>
|
||
<td>21.233380</td>
|
||
</tr>
|
||
<tr>
|
||
<th>3</th>
|
||
<td>0.528693</td>
|
||
<td>21.144427</td>
|
||
</tr>
|
||
<tr>
|
||
<th>4</th>
|
||
<td>0.509300</td>
|
||
<td>21.054549</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div></div></div>
|
||
</div>
|
||
<p>The result is a <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code> with one column for <code class="docutils literal notranslate"><span class="pre">gi</span></code> and one column for <code class="docutils literal notranslate"><span class="pre">g</span></code>, so we can pass it to <code class="docutils literal notranslate"><span class="pre">Path</span></code> like this:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">matplotlib.path</span> <span class="kn">import</span> <span class="n">Path</span>
|
||
|
||
<span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">loop_df</span><span class="p">)</span>
|
||
<span class="n">path</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>Path(array([[ 0.58757135, 21.41174601],
|
||
[ 0.56780097, 21.32246601],
|
||
[ 0.54813409, 21.23338001],
|
||
[ 0.5286928 , 21.14442701],
|
||
[ 0.50929987, 21.05454901],
|
||
[ 0.48991266, 20.96383501],
|
||
[ 0.47084777, 20.87386601],
|
||
[ 0.45222635, 20.78511001],
|
||
[ 0.43438902, 20.69865301],
|
||
[ 0.42745198, 20.66469601],
|
||
[ 0.42067029, 20.63135301],
|
||
[ 0.41402867, 20.59850601],
|
||
[ 0.40738016, 20.56529901],
|
||
[ 0.40088387, 20.53264001],
|
||
[ 0.39449608, 20.50023501],
|
||
[ 0.38843797, 20.46871801],
|
||
[ 0.38251577, 20.43765101],
|
||
[ 0.3766547 , 20.40653701],
|
||
[ 0.37088531, 20.37564701],
|
||
[ 0.36522325, 20.34505401],
|
||
[ 0.35962415, 20.31443001],
|
||
[ 0.35413292, 20.28413501],
|
||
[ 0.34871894, 20.25390101],
|
||
[ 0.34339273, 20.22385701],
|
||
[ 0.33815825, 20.19395801],
|
||
[ 0.33305724, 20.16427301],
|
||
[ 0.32820637, 20.13508501],
|
||
[ 0.32348139, 20.10604901],
|
||
[ 0.31883343, 20.07716101],
|
||
[ 0.31425423, 20.04833101],
|
||
[ 0.30974976, 20.01961701],
|
||
[ 0.30531997, 19.99097001],
|
||
[ 0.30097354, 19.96246401],
|
||
[ 0.29669999, 19.93401801],
|
||
[ 0.29250157, 19.90573101],
|
||
[ 0.28837983, 19.87746501],
|
||
[ 0.28441584, 19.84955001],
|
||
[ 0.28065057, 19.82188301],
|
||
[ 0.27700644, 19.79450101],
|
||
[ 0.27342328, 19.76713801],
|
||
[ 0.26989305, 19.73985301],
|
||
[ 0.26641258, 19.71265801],
|
||
[ 0.26298257, 19.68540001],
|
||
[ 0.25960216, 19.65824401],
|
||
[ 0.2562733 , 19.63113701],
|
||
[ 0.25299978, 19.60409301],
|
||
[ 0.24977307, 19.57714401],
|
||
[ 0.24660506, 19.55024001],
|
||
[ 0.24348829, 19.52341001],
|
||
[ 0.24042159, 19.49666601],
|
||
[ 0.23741737, 19.46998501],
|
||
[ 0.23447423, 19.44339301],
|
||
[ 0.23158726, 19.41688701],
|
||
[ 0.22876474, 19.39045101],
|
||
[ 0.22600432, 19.36410901],
|
||
[ 0.22330395, 19.33786601],
|
||
[ 0.220663 , 19.31170101],
|
||
[ 0.21808571, 19.28560101],
|
||
[ 0.21557456, 19.25960101],
|
||
[ 0.21312279, 19.23368701],
|
||
[ 0.21073349, 19.20785601],
|
||
[ 0.20840975, 19.18210401],
|
||
[ 0.20614799, 19.15640601],
|
||
[ 0.20395119, 19.13076401],
|
||
[ 0.20182156, 19.10523201],
|
||
[ 0.19975572, 19.07977101],
|
||
[ 0.19775195, 19.05436401],
|
||
[ 0.19581903, 19.02902801],
|
||
[ 0.19395701, 19.00376101],
|
||
[ 0.19216276, 18.97857301],
|
||
[ 0.19044513, 18.95347601],
|
||
[ 0.1888007 , 18.92850001],
|
||
[ 0.18723796, 18.90368201],
|
||
[ 0.18576648, 18.87905401],
|
||
[ 0.18438763, 18.85466301],
|
||
[ 0.18310871, 18.83056001],
|
||
[ 0.18193706, 18.80672701],
|
||
[ 0.18087817, 18.78327401],
|
||
[ 0.17993184, 18.76015001],
|
||
[ 0.17910244, 18.73740501],
|
||
[ 0.17838817, 18.71496101],
|
||
[ 0.17779005, 18.69282101],
|
||
[ 0.177312 , 18.67099501],
|
||
[ 0.17694971, 18.64944001],
|
||
[ 0.1767112 , 18.62815801],
|
||
[ 0.17659065, 18.60714001],
|
||
[ 0.17658939, 18.58636601],
|
||
[ 0.17671618, 18.56585701],
|
||
[ 0.17696696, 18.54562201],
|
||
[ 0.17733781, 18.52565801],
|
||
[ 0.1778346 , 18.50597901],
|
||
[ 0.17846661, 18.48656801],
|
||
[ 0.17922891, 18.46742401],
|
||
[ 0.18012796, 18.44859001],
|
||
[ 0.18116197, 18.43005501],
|
||
[ 0.18233604, 18.41181501],
|
||
[ 0.18363223, 18.39379401],
|
||
[ 0.18506009, 18.37602901],
|
||
[ 0.18660932, 18.35862101],
|
||
[ 0.18829849, 18.34153201],
|
||
[ 0.19012805, 18.32480701],
|
||
[ 0.19210919, 18.30851301],
|
||
[ 0.19422686, 18.29250401],
|
||
[ 0.1964951 , 18.27685701],
|
||
[ 0.19890209, 18.26156301],
|
||
[ 0.20145338, 18.24666001],
|
||
[ 0.20417715, 18.23260501],
|
||
[ 0.20705285, 18.21898101],
|
||
[ 0.21005661, 18.20562501],
|
||
[ 0.21319339, 18.19254201],
|
||
[ 0.22126873, 18.16185301],
|
||
[ 0.2300065 , 18.13259301],
|
||
[ 0.23950909, 18.10508001],
|
||
[ 0.24974677, 18.07932501],
|
||
[ 0.26066153, 18.05527801],
|
||
[ 0.27224553, 18.03295501],
|
||
[ 0.28447607, 18.01227601],
|
||
[ 0.40566013, 18.01227601],
|
||
[ 0.39412682, 18.03295501],
|
||
[ 0.38329907, 18.05527801],
|
||
[ 0.37320316, 18.07932501],
|
||
[ 0.36384734, 18.10508001],
|
||
[ 0.35529237, 18.13259301],
|
||
[ 0.34756872, 18.16185301],
|
||
[ 0.34056407, 18.19254201],
|
||
[ 0.33788593, 18.20562501],
|
||
[ 0.33535176, 18.21898101],
|
||
[ 0.33295648, 18.23260501],
|
||
[ 0.33072983, 18.24666001],
|
||
[ 0.32870734, 18.26156301],
|
||
[ 0.32684482, 18.27685701],
|
||
[ 0.3251355 , 18.29250401],
|
||
[ 0.32359167, 18.30851301],
|
||
[ 0.32219665, 18.32480701],
|
||
[ 0.32097089, 18.34153201],
|
||
[ 0.31990093, 18.35862101],
|
||
[ 0.31898485, 18.37602901],
|
||
[ 0.3182056 , 18.39379401],
|
||
[ 0.31756993, 18.41181501],
|
||
[ 0.31706705, 18.43005501],
|
||
[ 0.31671781, 18.44859001],
|
||
[ 0.3165174 , 18.46742401],
|
||
[ 0.31646817, 18.48656801],
|
||
[ 0.3165622 , 18.50597901],
|
||
[ 0.31680458, 18.52565801],
|
||
[ 0.31718682, 18.54562201],
|
||
[ 0.31770268, 18.56585701],
|
||
[ 0.31835632, 18.58636601],
|
||
[ 0.31915162, 18.60714001],
|
||
[ 0.32007915, 18.62815801],
|
||
[ 0.3211385 , 18.64944001],
|
||
[ 0.32233599, 18.67099501],
|
||
[ 0.32366367, 18.69282101],
|
||
[ 0.32512771, 18.71496101],
|
||
[ 0.32672398, 18.73740501],
|
||
[ 0.32845154, 18.76015001],
|
||
[ 0.33031546, 18.78327401],
|
||
[ 0.33230964, 18.80672701],
|
||
[ 0.33443651, 18.83056001],
|
||
[ 0.3366864 , 18.85466301],
|
||
[ 0.3390529 , 18.87905401],
|
||
[ 0.34152681, 18.90368201],
|
||
[ 0.34410502, 18.92850001],
|
||
[ 0.34677677, 18.95347601],
|
||
[ 0.34953217, 18.97857301],
|
||
[ 0.35237348, 19.00376101],
|
||
[ 0.35529144, 19.02902801],
|
||
[ 0.35828883, 19.05436401],
|
||
[ 0.36136575, 19.07977101],
|
||
[ 0.36451277, 19.10523201],
|
||
[ 0.36773241, 19.13076401],
|
||
[ 0.37102978, 19.15640601],
|
||
[ 0.37440044, 19.18210401],
|
||
[ 0.37784139, 19.20785601],
|
||
[ 0.38135736, 19.23368701],
|
||
[ 0.38494552, 19.25960101],
|
||
[ 0.388603 , 19.28560101],
|
||
[ 0.39233725, 19.31170101],
|
||
[ 0.39614435, 19.33786601],
|
||
[ 0.40002069, 19.36410901],
|
||
[ 0.40396796, 19.39045101],
|
||
[ 0.40798805, 19.41688701],
|
||
[ 0.41208235, 19.44339301],
|
||
[ 0.41624335, 19.46998501],
|
||
[ 0.42047622, 19.49666601],
|
||
[ 0.42478124, 19.52341001],
|
||
[ 0.42914714, 19.55024001],
|
||
[ 0.43357463, 19.57714401],
|
||
[ 0.43806989, 19.60409301],
|
||
[ 0.44262347, 19.63113701],
|
||
[ 0.44724247, 19.65824401],
|
||
[ 0.4519225 , 19.68540001],
|
||
[ 0.45666424, 19.71265801],
|
||
[ 0.46146067, 19.73985301],
|
||
[ 0.46631851, 19.76713801],
|
||
[ 0.47124047, 19.79450101],
|
||
[ 0.47623175, 19.82188301],
|
||
[ 0.48136578, 19.84955001],
|
||
[ 0.48671855, 19.87746501],
|
||
[ 0.49225451, 19.90573101],
|
||
[ 0.49787627, 19.93401801],
|
||
[ 0.50358931, 19.96246401],
|
||
[ 0.50938655, 19.99097001],
|
||
[ 0.51528266, 20.01961701],
|
||
[ 0.52126534, 20.04833101],
|
||
[ 0.52733726, 20.07716101],
|
||
[ 0.53348957, 20.10604901],
|
||
[ 0.53973535, 20.13508501],
|
||
[ 0.54612384, 20.16427301],
|
||
[ 0.55279781, 20.19395801],
|
||
[ 0.55962597, 20.22385701],
|
||
[ 0.56656311, 20.25390101],
|
||
[ 0.57360789, 20.28413501],
|
||
[ 0.58074299, 20.31443001],
|
||
[ 0.5880138 , 20.34505401],
|
||
[ 0.59535596, 20.37564701],
|
||
[ 0.60283203, 20.40653701],
|
||
[ 0.61042265, 20.43765101],
|
||
[ 0.61808231, 20.46871801],
|
||
[ 0.62591386, 20.50023501],
|
||
[ 0.63413647, 20.53264001],
|
||
[ 0.64249372, 20.56529901],
|
||
[ 0.65104657, 20.59850601],
|
||
[ 0.659584 , 20.63135301],
|
||
[ 0.66830253, 20.66469601],
|
||
[ 0.67722496, 20.69865301],
|
||
[ 0.70017638, 20.78511001],
|
||
[ 0.72413715, 20.87386601],
|
||
[ 0.74870785, 20.96383501],
|
||
[ 0.77374297, 21.05454901],
|
||
[ 0.7988286 , 21.14442701],
|
||
[ 0.8240001 , 21.23338001],
|
||
[ 0.84950281, 21.32246601],
|
||
[ 0.8752204 , 21.41174601]]), None)
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The result is a <code class="docutils literal notranslate"><span class="pre">Path</span></code> object that represents the polygon.</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">Path</span></code> provides <code class="docutils literal notranslate"><span class="pre">contains_points</span></code>, which figures out which points are inside the polygon.</p>
|
||
<p>To test it, we’ll create a list with two points, one inside the polygon and one outside.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">points</span> <span class="o">=</span> <span class="p">[(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mi">20</span><span class="p">),</span>
|
||
<span class="p">(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mi">16</span><span class="p">)]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can make sure <code class="docutils literal notranslate"><span class="pre">contains_points</span></code> does what we expect.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">inside</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">contains_points</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
|
||
<span class="n">inside</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>array([ True, False])
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The result is an array of Boolean values.</p>
|
||
<p>We are almost ready to select stars whose photometry data falls in this polygon. But first we need to do some data cleaning.</p>
|
||
</div>
|
||
<div class="section" id="reloading-the-data">
|
||
<h2>Reloading the data<a class="headerlink" href="#reloading-the-data" title="Permalink to this headline">¶</a></h2>
|
||
<p>Now we need to combine the photometry data with the list of candidate stars we identified in a previous notebook. The following cell downloads it:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
|
||
<span class="kn">from</span> <span class="nn">wget</span> <span class="kn">import</span> <span class="n">download</span>
|
||
|
||
<span class="n">filename</span> <span class="o">=</span> <span class="s1">'gd1_candidates.hdf5'</span>
|
||
<span class="n">filepath</span> <span class="o">=</span> <span class="s1">'https://github.com/AllenDowney/AstronomicalData/raw/main/data/'</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">download</span><span class="p">(</span><span class="n">filepath</span><span class="o">+</span><span class="n">filename</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
|
||
<span class="n">candidate_df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'candidate_df'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">candidate_df</span></code> is the Pandas DataFrame that contains the results from Lesson 4, which selects stars likely to be in GD-1 based on proper motion. It also includes position and proper motion transformed to the ICRS frame.</p>
|
||
</div>
|
||
<div class="section" id="merging-photometry-data">
|
||
<h2>Merging photometry data<a class="headerlink" href="#merging-photometry-data" title="Permalink to this headline">¶</a></h2>
|
||
<p>Before we select stars based on photometry data, we have to solve two problems:</p>
|
||
<ol class="simple">
|
||
<li><p>We only have Pan-STARRS data for some stars in <code class="docutils literal notranslate"><span class="pre">candidate_df</span></code>.</p></li>
|
||
<li><p>Even for the stars where we have Pan-STARRS data in <code class="docutils literal notranslate"><span class="pre">photo_table</span></code>, some photometry data is missing.</p></li>
|
||
</ol>
|
||
<p>We will solve these problems in two step:</p>
|
||
<ol class="simple">
|
||
<li><p>We’ll merge the data from <code class="docutils literal notranslate"><span class="pre">candidate_df</span></code> and <code class="docutils literal notranslate"><span class="pre">photo_table</span></code> into a single Pandas <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code>.</p></li>
|
||
<li><p>We’ll use Pandas functions to deal with missing data.</p></li>
|
||
</ol>
|
||
<p><code class="docutils literal notranslate"><span class="pre">candidate_df</span></code> is already a <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code>, but <code class="docutils literal notranslate"><span class="pre">results</span></code> is an Astropy <code class="docutils literal notranslate"><span class="pre">Table</span></code>. Let’s convert it to Pandas:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">photo_df</span> <span class="o">=</span> <span class="n">photo_table</span><span class="o">.</span><span class="n">to_pandas</span><span class="p">()</span>
|
||
|
||
<span class="k">for</span> <span class="n">colname</span> <span class="ow">in</span> <span class="n">photo_df</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">colname</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>source_id
|
||
g_mean_psf_mag
|
||
i_mean_psf_mag
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we want to combine <code class="docutils literal notranslate"><span class="pre">candidate_df</span></code> and <code class="docutils literal notranslate"><span class="pre">photo_df</span></code> into a single table, using <code class="docutils literal notranslate"><span class="pre">source_id</span></code> to match up the rows.</p>
|
||
<p>You might recognize this task; it’s the same as the JOIN operation in ADQL/SQL.</p>
|
||
<p>Pandas provides a function called <code class="docutils literal notranslate"><span class="pre">merge</span></code> that does what we want. Here’s how we use it.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">merged</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">candidate_df</span><span class="p">,</span>
|
||
<span class="n">photo_df</span><span class="p">,</span>
|
||
<span class="n">on</span><span class="o">=</span><span class="s1">'source_id'</span><span class="p">,</span>
|
||
<span class="n">how</span><span class="o">=</span><span class="s1">'left'</span><span class="p">)</span>
|
||
<span class="n">merged</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_html"><div>
|
||
<style scoped>
|
||
.dataframe tbody tr th:only-of-type {
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.dataframe tbody tr th {
|
||
vertical-align: top;
|
||
}
|
||
|
||
.dataframe thead th {
|
||
text-align: right;
|
||
}
|
||
</style>
|
||
<table border="1" class="dataframe">
|
||
<thead>
|
||
<tr style="text-align: right;">
|
||
<th></th>
|
||
<th>source_id</th>
|
||
<th>ra</th>
|
||
<th>dec</th>
|
||
<th>pmra</th>
|
||
<th>pmdec</th>
|
||
<th>parallax</th>
|
||
<th>radial_velocity</th>
|
||
<th>phi1</th>
|
||
<th>phi2</th>
|
||
<th>pm_phi1</th>
|
||
<th>pm_phi2</th>
|
||
<th>g_mean_psf_mag</th>
|
||
<th>i_mean_psf_mag</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<th>0</th>
|
||
<td>635559124339440000</td>
|
||
<td>137.586717</td>
|
||
<td>19.196544</td>
|
||
<td>-3.770522</td>
|
||
<td>-12.490482</td>
|
||
<td>0.791393</td>
|
||
<td>NaN</td>
|
||
<td>-59.630489</td>
|
||
<td>-1.216485</td>
|
||
<td>-7.361363</td>
|
||
<td>-0.592633</td>
|
||
<td>NaN</td>
|
||
<td>NaN</td>
|
||
</tr>
|
||
<tr>
|
||
<th>1</th>
|
||
<td>635860218726658176</td>
|
||
<td>138.518707</td>
|
||
<td>19.092339</td>
|
||
<td>-5.941679</td>
|
||
<td>-11.346409</td>
|
||
<td>0.307456</td>
|
||
<td>NaN</td>
|
||
<td>-59.247330</td>
|
||
<td>-2.016078</td>
|
||
<td>-7.527126</td>
|
||
<td>1.748779</td>
|
||
<td>17.8978</td>
|
||
<td>17.517401</td>
|
||
</tr>
|
||
<tr>
|
||
<th>2</th>
|
||
<td>635674126383965568</td>
|
||
<td>138.842874</td>
|
||
<td>19.031798</td>
|
||
<td>-3.897001</td>
|
||
<td>-12.702780</td>
|
||
<td>0.779463</td>
|
||
<td>NaN</td>
|
||
<td>-59.133391</td>
|
||
<td>-2.306901</td>
|
||
<td>-7.560608</td>
|
||
<td>-0.741800</td>
|
||
<td>19.2873</td>
|
||
<td>17.678101</td>
|
||
</tr>
|
||
<tr>
|
||
<th>3</th>
|
||
<td>635535454774983040</td>
|
||
<td>137.837752</td>
|
||
<td>18.864007</td>
|
||
<td>-4.335041</td>
|
||
<td>-14.492309</td>
|
||
<td>0.314514</td>
|
||
<td>NaN</td>
|
||
<td>-59.785300</td>
|
||
<td>-1.594569</td>
|
||
<td>-9.357536</td>
|
||
<td>-1.218492</td>
|
||
<td>16.9238</td>
|
||
<td>16.478100</td>
|
||
</tr>
|
||
<tr>
|
||
<th>4</th>
|
||
<td>635497276810313600</td>
|
||
<td>138.044516</td>
|
||
<td>19.009471</td>
|
||
<td>-7.172931</td>
|
||
<td>-12.291499</td>
|
||
<td>0.425404</td>
|
||
<td>NaN</td>
|
||
<td>-59.557744</td>
|
||
<td>-1.682147</td>
|
||
<td>-9.000831</td>
|
||
<td>2.334407</td>
|
||
<td>19.9242</td>
|
||
<td>18.334000</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div></div></div>
|
||
</div>
|
||
<p>The first argument is the “left” table, the second argument is the “right” table, and the keyword argument <code class="docutils literal notranslate"><span class="pre">on='source_id'</span></code> specifies a column to use to match up the rows.</p>
|
||
<p>The argument <code class="docutils literal notranslate"><span class="pre">how='left'</span></code> means that the result should have all rows from the left table, even if some of them don’t match up with a row in the right table.</p>
|
||
<p>If you are interested in the other options for <code class="docutils literal notranslate"><span class="pre">how</span></code>, you can <a class="reference external" href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html">read the documentation of <code class="docutils literal notranslate"><span class="pre">merge</span></code></a>.</p>
|
||
<p>You can also do different types of join in ADQL/SQL; <a class="reference external" href="https://www.w3schools.com/sql/sql_join.asp">you can read about that here</a>.</p>
|
||
<p>The result is a <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code> that contains the same number of rows as <code class="docutils literal notranslate"><span class="pre">candidate_df</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">candidate_df</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">photo_df</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">merged</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>(7346, 3724, 7346)
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>And all columns from both tables.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">colname</span> <span class="ow">in</span> <span class="n">merged</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">colname</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>source_id
|
||
ra
|
||
dec
|
||
pmra
|
||
pmdec
|
||
parallax
|
||
radial_velocity
|
||
phi1
|
||
phi2
|
||
pm_phi1
|
||
pm_phi2
|
||
g_mean_psf_mag
|
||
i_mean_psf_mag
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p><strong>Detail</strong> You might notice that Pandas also provides a function called <code class="docutils literal notranslate"><span class="pre">join</span></code>; it does almost the same thing, but the interface is slightly different. We think <code class="docutils literal notranslate"><span class="pre">merge</span></code> is a little easier to use, so that’s what we chose. It’s also more consistent with JOIN in SQL, so if you learn how to use <code class="docutils literal notranslate"><span class="pre">pd.merge</span></code>, you are also learning how to use SQL JOIN.</p>
|
||
<p>Also, someone might ask why we have to use Pandas to do this join; why didn’t we do it in ADQL. The answer is that we could have done that, but since we already have the data we need, we should probably do the computation locally rather than make another round trip to the Gaia server.</p>
|
||
</div>
|
||
<div class="section" id="missing-data">
|
||
<h2>Missing data<a class="headerlink" href="#missing-data" title="Permalink to this headline">¶</a></h2>
|
||
<p>Let’s add columns to the merged table for magnitude and color.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">merged</span><span class="p">[</span><span class="s1">'mag'</span><span class="p">]</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="s1">'g_mean_psf_mag'</span><span class="p">]</span>
|
||
<span class="n">merged</span><span class="p">[</span><span class="s1">'color'</span><span class="p">]</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="s1">'g_mean_psf_mag'</span><span class="p">]</span> <span class="o">-</span> <span class="n">merged</span><span class="p">[</span><span class="s1">'i_mean_psf_mag'</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>These columns contain the special value <code class="docutils literal notranslate"><span class="pre">NaN</span></code> where we are missing data.</p>
|
||
<p>We can use <code class="docutils literal notranslate"><span class="pre">notnull</span></code> to see which rows contain value data, that is, not null values.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">merged</span><span class="p">[</span><span class="s1">'color'</span><span class="p">]</span><span class="o">.</span><span class="n">notnull</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>0 False
|
||
1 True
|
||
2 True
|
||
3 True
|
||
4 True
|
||
...
|
||
7341 True
|
||
7342 False
|
||
7343 False
|
||
7344 True
|
||
7345 False
|
||
Name: color, Length: 7346, dtype: bool
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>And <code class="docutils literal notranslate"><span class="pre">sum</span></code> to count the number of valid values.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">merged</span><span class="p">[</span><span class="s1">'color'</span><span class="p">]</span><span class="o">.</span><span class="n">notnull</span><span class="p">()</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>3724
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>For scientific purposes, it’s not obvious what we should do with candidate stars if we don’t have photometry data. Should we give them the benefit of the doubt or leave them out?</p>
|
||
<p>In part the answer depends on the goal: are we trying to identify more stars that might be in GD-1, or a smaller set of stars that have higher probability?</p>
|
||
<p>In the next section, we’ll leave them out, but you can experiment with the alternative.</p>
|
||
</div>
|
||
<div class="section" id="selecting-based-on-photometry">
|
||
<h2>Selecting based on photometry<a class="headerlink" href="#selecting-based-on-photometry" title="Permalink to this headline">¶</a></h2>
|
||
<p>Now let’s see how many of these points are inside the polygon we chose.</p>
|
||
<p>We can use a list of column names to select <code class="docutils literal notranslate"><span class="pre">color</span></code> and <code class="docutils literal notranslate"><span class="pre">mag</span></code>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">points</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[[</span><span class="s1">'color'</span><span class="p">,</span> <span class="s1">'mag'</span><span class="p">]]</span>
|
||
<span class="n">points</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_html"><div>
|
||
<style scoped>
|
||
.dataframe tbody tr th:only-of-type {
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.dataframe tbody tr th {
|
||
vertical-align: top;
|
||
}
|
||
|
||
.dataframe thead th {
|
||
text-align: right;
|
||
}
|
||
</style>
|
||
<table border="1" class="dataframe">
|
||
<thead>
|
||
<tr style="text-align: right;">
|
||
<th></th>
|
||
<th>color</th>
|
||
<th>mag</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<th>0</th>
|
||
<td>NaN</td>
|
||
<td>NaN</td>
|
||
</tr>
|
||
<tr>
|
||
<th>1</th>
|
||
<td>0.3804</td>
|
||
<td>17.8978</td>
|
||
</tr>
|
||
<tr>
|
||
<th>2</th>
|
||
<td>1.6092</td>
|
||
<td>19.2873</td>
|
||
</tr>
|
||
<tr>
|
||
<th>3</th>
|
||
<td>0.4457</td>
|
||
<td>16.9238</td>
|
||
</tr>
|
||
<tr>
|
||
<th>4</th>
|
||
<td>1.5902</td>
|
||
<td>19.9242</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div></div></div>
|
||
</div>
|
||
<p>The result is a <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code> that can be treated as a sequence of coordinates, so we can pass it to <code class="docutils literal notranslate"><span class="pre">contains_points</span></code>:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">inside</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">contains_points</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
|
||
<span class="n">inside</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>array([False, False, False, ..., False, False, False])
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>The result is a Boolean array. We can use <code class="docutils literal notranslate"><span class="pre">sum</span></code> to see how many stars fall in the polygon.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">inside</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>464
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we can use <code class="docutils literal notranslate"><span class="pre">inside</span></code> as a mask to select stars that fall inside the polygon.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">selected2</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="n">inside</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Let’s make a color-magnitude plot one more time, highlighting the selected stars with green <code class="docutils literal notranslate"><span class="pre">x</span></code> marks.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">plot_cmd</span><span class="p">(</span><span class="n">photo_table</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">gi</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
|
||
<span class="n">loop</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">selected2</span><span class="p">[</span><span class="s1">'color'</span><span class="p">],</span> <span class="n">selected2</span><span class="p">[</span><span class="s1">'mag'</span><span class="p">],</span> <span class="s1">'g.'</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_114_0.png" src="_images/06_photo_114_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>It looks like the selected stars are, in fact, inside the polygon, which means they have photometry data consistent with GD-1.</p>
|
||
<p>Finally, we can plot the coordinates of the selected stars:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mf">2.5</span><span class="p">))</span>
|
||
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">selected2</span><span class="p">[</span><span class="s1">'phi1'</span><span class="p">]</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">selected2</span><span class="p">[</span><span class="s1">'phi2'</span><span class="p">]</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'ko'</span><span class="p">,</span> <span class="n">markersize</span><span class="o">=</span><span class="mf">0.7</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.9</span><span class="p">)</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">'ra (degree GD1)'</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">'dec (degree GD1)'</span><span class="p">)</span>
|
||
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s1">'equal'</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<img alt="_images/06_photo_116_0.png" src="_images/06_photo_116_0.png" />
|
||
</div>
|
||
</div>
|
||
<p>This example includes two new Matplotlib commands:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">figure</span></code> creates the figure. In previous examples, we didn’t have to use this function; the figure was created automatically. But when we call it explicitly, we can provide arguments like <code class="docutils literal notranslate"><span class="pre">figsize</span></code>, which sets the size of the figure.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">axis</span></code> with the parameter <code class="docutils literal notranslate"><span class="pre">equal</span></code> sets up the axes so a unit is the same size along the <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code> axes.</p></li>
|
||
</ul>
|
||
<p>In an example like this, where <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code> represent coordinates in space, equal axes ensures that the distance between points is represented accurately.</p>
|
||
</div>
|
||
<div class="section" id="write-the-data">
|
||
<h2>Write the data<a class="headerlink" href="#write-the-data" title="Permalink to this headline">¶</a></h2>
|
||
<p>Let’s write the merged DataFrame to a file.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">filename</span> <span class="o">=</span> <span class="s1">'gd1_merged.hdf5'</span>
|
||
|
||
<span class="n">merged</span><span class="o">.</span><span class="n">to_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'merged'</span><span class="p">)</span>
|
||
<span class="n">selected2</span><span class="o">.</span><span class="n">to_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'selected2'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="o">!</span>ls -lh gd1_merged.hdf5
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>-rw-rw-r-- 1 downey downey 1.1M Dec 14 14:24 gd1_merged.hdf5
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>If you are using Windows, <code class="docutils literal notranslate"><span class="pre">ls</span></code> might not work; in that case, try:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>!dir gd1_merged.hdf5
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="save-the-polygon">
|
||
<h2>Save the polygon<a class="headerlink" href="#save-the-polygon" title="Permalink to this headline">¶</a></h2>
|
||
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Reproducibility#Reproducible_research">Reproducibile research</a> is “the idea that … the full computational environment used to produce the results in the paper such as the code, data, etc. can be used to reproduce the results and create new work based on the research.”</p>
|
||
<p>This Jupyter notebook is an example of reproducible research because it contains all of the code needed to reproduce the results, including the database queries that download the data and and analysis.</p>
|
||
<p>In this lesson we used an isochrone to derive a polygon, which we used to select stars based on photometry.
|
||
So it is important to record the polygon as part of the data analysis pipeline.</p>
|
||
<p>Here’s how we can save it in an HDF file.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">filename</span> <span class="o">=</span> <span class="s1">'gd1_polygon.hdf5'</span>
|
||
<span class="n">loop</span><span class="o">.</span><span class="n">to_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'loop'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We can read it back like this.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">loop2</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_hdf</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">'loop'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>And verify that the data we read back is the same.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
|
||
<span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">loop</span> <span class="o">==</span> <span class="n">loop2</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>True
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="summary">
|
||
<h2>Summary<a class="headerlink" href="#summary" title="Permalink to this headline">¶</a></h2>
|
||
<p>In this notebook, we worked with two datasets: the list of candidate stars from Gaia and the photometry data from Pan-STARRS.</p>
|
||
<p>We drew a color-magnitude diagram and used it to identify stars we think are likely to be in GD-1.</p>
|
||
<p>Then we used a Pandas <code class="docutils literal notranslate"><span class="pre">merge</span></code> operation to combine the data into a single <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code>.</p>
|
||
</div>
|
||
<div class="section" id="best-practices">
|
||
<h2>Best practices<a class="headerlink" href="#best-practices" title="Permalink to this headline">¶</a></h2>
|
||
<ul class="simple">
|
||
<li><p>If you want to perform something like a database <code class="docutils literal notranslate"><span class="pre">JOIN</span></code> operation with data that is in a Pandas <code class="docutils literal notranslate"><span class="pre">DataFrame</span></code>, you can use the <code class="docutils literal notranslate"><span class="pre">join</span></code> or <code class="docutils literal notranslate"><span class="pre">merge</span></code> function. In many cases, <code class="docutils literal notranslate"><span class="pre">merge</span></code> is easier to use because the arguments are more like SQL.</p></li>
|
||
<li><p>Use Matplotlib options to control the size and aspect ratio of figures to make them easier to interpret. In this example, we scaled the axes so the size of a degree is equal along both axes.</p></li>
|
||
<li><p>Matplotlib also provides operations for working with points, polygons, and other geometric entities, so it’s not just for making figures.</p></li>
|
||
<li><p>Be sure to record every element of the data analysis pipeline that would be needed to replicate the results.</p></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<script type="text/x-thebe-config">
|
||
{
|
||
requestKernel: true,
|
||
binderOptions: {
|
||
repo: "binder-examples/jupyter-stacks-datascience",
|
||
ref: "master",
|
||
},
|
||
codeMirrorConfig: {
|
||
theme: "abcdef",
|
||
mode: "python"
|
||
},
|
||
kernelOptions: {
|
||
kernelName: "python3",
|
||
path: "./."
|
||
},
|
||
predefinedOutput: true
|
||
}
|
||
</script>
|
||
<script>kernelName = 'python3'</script>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class='prev-next-bottom'>
|
||
|
||
<a class='left-prev' id="prev-link" href="05_join.html" title="previous page">Joining Tables</a>
|
||
<a class='right-next' id="next-link" href="07_plot.html" title="next page">Visualization</a>
|
||
|
||
</div>
|
||
<footer class="footer mt-5 mt-md-0">
|
||
<div class="container">
|
||
<p>
|
||
|
||
By Allen B. Downey<br/>
|
||
|
||
© Copyright 2020.<br/>
|
||
</p>
|
||
</div>
|
||
</footer>
|
||
</main>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<script src="_static/js/index.30270b6e4c972e43c488.js"></script>
|
||
|
||
|
||
|
||
</body>
|
||
</html> |