Jekyll2022-05-14T01:47:49+00:00https://nicholasvadivelu.com/feed.xmlNicholas VadiveluA content-first, sliding sidebar theme for Jekyll.Nicholas Vadivelunicholas.vadivelu@gmail.comOptimizing k-Means in NumPy & SciPy2021-05-10T00:00:00+00:002021-05-10T00:00:00+00:00https://nicholasvadivelu.com/2021/05/10/fast-k-means<center>
<a href="https://colab.research.google.com/drive/1aLFM6K-ZJ7QkZoQFJ4QQ5xOvbN3OOndo?usp=sharing" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a>
</center>
<p>In this article, we’ll analyze and optimize the runtime of a basic implementation of the k-means algorithm using techniques like vectorization, broadcasting, sparse matrices, unbuffered operations, and more.
We’ll focus on generally applicable techniques for writing fast NumPy/SciPy and stay away from arcane tricks (no promises, though).</p>
<h2 id="k-means-crash-course">k-Means Crash Course</h2>
<p>Suppose you run a smartphone company and plan to sell a new phone in three sizes: small, medium, and large.
To figure out each size, you do a survey on your customers’ preferences.
Given this data on preferred sizes, how can you deduce the best phone sizes?</p>
<p>One approach is to use <em>clustering</em>: a procedure that discovers groups within data.
You can find 3 clusters in your data, then cater your phones to the average customer in each cluster.
One of the most popular algorithms for doing so is called <em>k-means</em>.</p>
<p>As the name implies, this algorithm aims to find $k$ clusters in your data.
Initially, k-means chooses $k$ random points in your data, called centroids.
Then, each point is assigned to the closest centroid, where “closeness” is measured by Euclidean distance.
Next, each centroid is updated to the average of all the points assigned to that cluster.
The algorithm repeats the previous two steps until convergence.
This post won’t detail the math behind this algorithm, as there are many great resources online that go more in depth.</p>
<h2 id="initial-implementation">Initial Implementation</h2>
<p>To focus on optimizing the core logic (i.e. the inner loop), we’ll make a few simplifying assumptions:</p>
<ol>
<li>The data is provided as a $n \times d$ array ($n$ data points, each of dimension $d$).</li>
<li>The algorithm runs for a fixed number of iterations (instead of checking convergence criteria).</li>
<li>All inputs/outputs are NumPy arrays.</li>
</ol>
<p>We’ll focus on a moderately sized problem with $n=5000$, $d=26$ and $k=26$.
In practice, k-means doesn’t work well when $d$ is too large, since the euclidean distance isn’t a great measure in high dimensions.
$k$ can vary a lot depending on the problem, but for the sake of simplicity, we’ll assume it’s similar in scale to $d$.</p>
<p>Given these constraints, here’s a reasonable first implementation:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kmeans</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">num_iter</span><span class="o">=</span><span class="mi">50</span><span class="p">):</span>
<span class="n">n</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">shape</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">replace</span><span class="o">=</span><span class="bp">False</span><span class="p">)]</span> <span class="c1"># (k, d)
</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">empty</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="c1"># (n,)
</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_iter</span><span class="p">):</span>
<span class="c1"># ASSIGNMENT STEP
</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">point</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="c1"># Compute euclidean distance to each centroid
</span> <span class="n">distances</span> <span class="o">=</span> <span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="n">norm</span><span class="p">(</span><span class="n">point</span> <span class="o">-</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">centroids</span><span class="p">]</span>
<span class="c1"># Find the closest centroid
</span> <span class="n">labels</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argmin</span><span class="p">(</span><span class="n">distances</span><span class="p">)</span>
<span class="c1"># UPDATE STEP
</span> <span class="c1"># For each of the k groups, use boolean indexing to extract
</span> <span class="c1"># the points that belong to that group.
</span> <span class="c1"># Then, find the mean vector within that group.
</span> <span class="n">centroids</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">stack</span><span class="p">([</span><span class="n">data</span><span class="p">[</span><span class="n">labels</span><span class="o">==</span><span class="n">i</span><span class="p">].</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">)])</span> <span class="c1"># (k, d)
</span>
<span class="k">return</span> <span class="n">centroids</span>
<span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="mi">5000</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">26</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="p">))</span> <span class="c1"># dummy data
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">kmeans</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="c1"># magic function from Jupyter Notebooks
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
1 loop, best of 5: 51.7 s per loop
</pre>
</div>
<p>The implementation is straightforward, except for the small optimization of using <code class="language-plaintext highlighter-rouge">np.empty</code> instead of <code class="language-plaintext highlighter-rouge">np.zeros</code>: since we know we will be assigning a value to every element in the array, it’s a waste to initialize with 0s.
Instead, numpy will simply allocate a vector of appropriate size and return the uninitialized vector with garbage values.</p>
<p>We’ll optimize the assignment step and update step seperately, so we’ll refactor the method as follows.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kmeans</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">num_iter</span><span class="o">=</span><span class="mi">50</span><span class="p">):</span>
<span class="n">n</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">shape</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">replace</span><span class="o">=</span><span class="bp">False</span><span class="p">)]</span> <span class="c1"># (k, d)
</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_iter</span><span class="p">):</span>
<span class="n">labels</span> <span class="o">=</span> <span class="n">assignment_step</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">)</span> <span class="c1"># (n,)
</span> <span class="n">centroids</span> <span class="o">=</span> <span class="n">update_step</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="c1"># (k, d)
</span>
<span class="k">return</span> <span class="n">centroids</span>
</code></pre></div></div>
<h2 id="optimizing-the-assignment-step">Optimizing the Assignment Step</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">assignment_step_v1</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">):</span>
<span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">empty</span><span class="p">(</span><span class="n">data</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="c1"># (n,)
</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">point</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">distances</span> <span class="o">=</span> <span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="n">norm</span><span class="p">(</span><span class="n">point</span> <span class="o">-</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">centroids</span><span class="p">]</span>
<span class="n">labels</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argmin</span><span class="p">(</span><span class="n">distances</span><span class="p">)</span>
<span class="k">return</span> <span class="n">labels</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">replace</span><span class="o">=</span><span class="bp">False</span><span class="p">)]</span> <span class="c1"># (k, d)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">assignment_step_v1</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1 loop, best of 5: 1.01 s per loop
</pre>
</div>
<p>In general, the slowest thing you can do when processing data in Python is to use pure Python.
As a rule of thumb, you should avoid Python loops unless your code has some sequential dependence (i.e. the current iteration depends on the previous).
In our assignment step, we use two python loops that can both be <em>vectorized</em>, since each iteration of the loops don’t depend on other iterations.</p>
<p>We do this via <a href="https://numpy.org/doc/stable/user/basics.broadcasting.html"><em>broadcasting</em></a>.
Instead of finding the distance between each data point with each centroid, we find the distance between each data point and all the centroids at once.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">assignment_step_v2</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">):</span>
<span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">empty</span><span class="p">(</span><span class="n">data</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="c1"># (n, )
</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">point</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">distances</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="n">norm</span><span class="p">(</span><span class="n">point</span> <span class="o">-</span> <span class="n">centroids</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># (k,)
</span> <span class="n">labels</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argmin</span><span class="p">(</span><span class="n">distances</span><span class="p">)</span>
<span class="k">return</span> <span class="n">labels</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">assignment_step_v2</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
10 loops, best of 5: 72.6 ms per loop
</pre>
</div>
<p>Recall that <code class="language-plaintext highlighter-rouge">point.shape == (d,)</code>, and <code class="language-plaintext highlighter-rouge">centroids.shape == (k, d)</code>.
When we do <code class="language-plaintext highlighter-rouge">point - centroids</code>, the NumPy <em>pretends</em> <code class="language-plaintext highlighter-rouge">point</code> is replicated <code class="language-plaintext highlighter-rouge">k</code> times into an array of shape <code class="language-plaintext highlighter-rouge">(k, d)</code> before doing the subtraction. Then, we compute the norm along the <code class="language-plaintext highlighter-rouge">axis=1</code>, to obtain <code class="language-plaintext highlighter-rouge">k</code> distances.</p>
<p>The key word is “pretending”: actually materializing the larger array would waste space and time.
Broadcasting simply interprets the existing data in a different (usually larger) shape.</p>
<p>This simple change brings with it a significant speedup.
We can take this idea one step further: use broadcasting to vectorize computing the distance between every point and every centroid:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">assignment_step_v3</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">):</span>
<span class="n">diff</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="o">-</span> <span class="n">centroids</span><span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="c1"># (n, k, d)
</span> <span class="n">distances</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="n">norm</span><span class="p">(</span><span class="n">diff</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># (n, k)
</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argmin</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># (n,)
</span> <span class="k">return</span> <span class="n">labels</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">assignment_step_v3</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 loops, best of 5: 18.1 ms per loop
</pre>
</div>
<p>When you index with <code class="language-plaintext highlighter-rouge">None</code> in NumPy, you are adding a new axis (equivalent to indexing with <code class="language-plaintext highlighter-rouge">np.newaxis</code>).</p>
<p>Thus, <code class="language-plaintext highlighter-rouge">centroids.shape == (k, d)</code> and <code class="language-plaintext highlighter-rouge">centroids[None].shape == (1, k, d)</code>.
For data, we insert a new axis in the second spot, so <code class="language-plaintext highlighter-rouge">data[:, None].shape == (n, 1, d)</code>.
Recall that indexing with <code class="language-plaintext highlighter-rouge">:</code> selects the entire axis.</p>
<p>Now, <code class="language-plaintext highlighter-rouge">diff.shape == (n, k, d)</code>.
Effectively, NumPy replicated <code class="language-plaintext highlighter-rouge">data</code> <code class="language-plaintext highlighter-rouge">k</code> times along the second axis, and replicated <code class="language-plaintext highlighter-rouge">centroids</code> <code class="language-plaintext highlighter-rouge">n</code> times along the first axis.
Therefore, <code class="language-plaintext highlighter-rouge">diff</code> contains all the pairwise differences.</p>
<p>Then, we compute the norm along <code class="language-plaintext highlighter-rouge">d</code> once again, then compute the argmin along <code class="language-plaintext highlighter-rouge">k</code> to get our final labels.</p>
<p>Eliminating these loops resulted in an order of magnitude improvement, though we can still do slightly better. The euclidean distance between two points is computed as follows:</p>
\[d(x, y) = \sqrt{\sum_{i=1}^d (x_i - y_i)^2}\]
<p>The square root here is a monotonic function, so removing it won’t change the relative order of the centroids.
Let’s get rid of it:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">assignment_step_v4</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">):</span>
<span class="n">diff</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="o">-</span> <span class="n">centroids</span><span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="c1"># (n, k, d)
</span> <span class="n">distances</span> <span class="o">=</span> <span class="p">(</span><span class="n">diff</span><span class="o">**</span><span class="mi">2</span><span class="p">).</span><span class="nb">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># (n, k)
</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argmin</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># (n,)
</span> <span class="k">return</span> <span class="n">labels</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">assignment_step_v4</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 loops, best of 5: 17.8 ms per loop
</pre>
</div>
<p>Though this brings a slight improvement, it’s not entirely due to removing the relatively cheap square root operation.
The <code class="language-plaintext highlighter-rouge">np.linalg.norm</code> function has a lot of preamble code, thus the difference between <code class="language-plaintext highlighter-rouge">v3</code> and <code class="language-plaintext highlighter-rouge">v4</code> will get smaller as the inputs grow larger.</p>
<p>Notice, <code class="language-plaintext highlighter-rouge">(diff**2)</code> produces an intermediate <code class="language-plaintext highlighter-rouge">(n, k, d)</code> array before we reduce it via the <code class="language-plaintext highlighter-rouge">sum</code>.
<code class="language-plaintext highlighter-rouge">np.linalg.norm</code> on the other hand does not: the square and sum happen at the same time.
A line-by-line profile would reveal that it’s not really a bottleneck for our current input size, but nonetheless, we can get rid of it without adding complexity.</p>
<p><code class="language-plaintext highlighter-rouge">np.einsum</code> can do the square and reduction in one step, avoiding the intermediate array. <code class="language-plaintext highlighter-rouge">np.einsum</code> allows you to express products and sums in a concise syntax, a nice explanation can be found <a href="https://rockt.github.io/2018/04/30/einsum">here</a>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">assignment_step_v5</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">):</span>
<span class="n">diff</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="o">-</span> <span class="n">centroids</span><span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="c1"># (n, k, d)
</span> <span class="n">distances</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">'nkd,nkd->nk'</span><span class="p">,</span> <span class="n">diff</span><span class="p">,</span> <span class="n">diff</span><span class="p">)</span> <span class="c1"># (n, k)
</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argmin</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># (n,)
</span> <span class="k">return</span> <span class="n">labels</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">assignment_step_v5</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">centroids</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 loops, best of 5: 9.94 ms per loop
</pre>
</div>
<p><code class="language-plaintext highlighter-rouge">nkd,nkd</code> indicates that we’ll supply two arrays of shape <code class="language-plaintext highlighter-rouge">(n, k, d)</code> as input, and that the procedure should multiple them together elementwise (axes with the same letters are multiplied). <code class="language-plaintext highlighter-rouge">->nk</code> indicates that the result will have shape <code class="language-plaintext highlighter-rouge">(n, k)</code>, and thus <code class="language-plaintext highlighter-rouge">einsum</code> will sum across the missing dimension <code class="language-plaintext highlighter-rouge">d</code>.</p>
<p><code class="language-plaintext highlighter-rouge">np.einsum</code> will also choose the best implementation for the given expresssion, which is why the time will always be similar to or better than <code class="language-plaintext highlighter-rouge">np.linalg.norm</code>.</p>
<p>Let’s compare these algorithms across various values for <code class="language-plaintext highlighter-rouge">n</code>, <code class="language-plaintext highlighter-rouge">d</code>, and <code class="language-plaintext highlighter-rouge">k</code>:</p>
<p><img src="/assets/images/posts/fast-k-means/assignment_cmp.svg#center" alt="" /></p>
<p>Each <code class="language-plaintext highlighter-rouge">n, d, k</code> triplet is run 20 times.
The mean with a 95% confidence band is plotted above.
The methods are grouped into different rows to show trends more clearly, as the latter 3 are significantly faster than the former 2.</p>
<p>We can see the operations are linear with respect to all of the inputs.
For <code class="language-plaintext highlighter-rouge">v1</code> and <code class="language-plaintext highlighter-rouge">v2</code>, the relationship appears constant with respect to <code class="language-plaintext highlighter-rouge">d</code> because the loops over <code class="language-plaintext highlighter-rouge">k</code> and <code class="language-plaintext highlighter-rouge">n</code> take dominate the runtime.
When we remove the loop over <code class="language-plaintext highlighter-rouge">k</code> in 2, the linear relationship disappears in <code class="language-plaintext highlighter-rouge">k</code> because the time is dominated by the loop over <code class="language-plaintext highlighter-rouge">n</code>.
We see that for larger sized inputs, <code class="language-plaintext highlighter-rouge">v3</code> and <code class="language-plaintext highlighter-rouge">v4</code> are about the same because the overhead of <code class="language-plaintext highlighter-rouge">v3</code> becomes negligible.
<code class="language-plaintext highlighter-rouge">v5</code> is consistently the fastest due to superior implementation selection for the given inputs.</p>
<p>For the assignment step, our runtime cuts primarily came from removing Python loops via vectorization.
Optimizing the <code class="language-plaintext highlighter-rouge">update_step</code> will be a bit more tricky.</p>
<h2 id="optimizing-the-update-step">Optimizing the Update Step</h2>
<p>For the update step, we <em>group-by</em> the label then <em>aggregate</em> via a mean.
I wrote a blog post comparing ways to perform this operation in NumPy <a href="https://nicholasvadivelu.com/2021/02/16/groupby-from-scratch/">here</a>, which I recommend reading before proceeding.
This section will use some of those techniques, including boolean masking, onehot matrices, sparse matrices, unbuffered addition, and <code class="language-plaintext highlighter-rouge">np.bincount</code>.
Unlike the previous blog post, we’re aggregating a vector-values (centroids) instead of scalars, thus the explanations will focus on the key changes needed for vectors.</p>
<p>Our goal is to optimize the inner loop of the computation.
So, any arrays that can be pre-computed (outside the loop) will be passed to <code class="language-plaintext highlighter-rouge">update_step</code> as arguments (i.e. not timed).</p>
<p>Our current <code class="language-plaintext highlighter-rouge">update_step</code> uses boolean indexing to select the data points in each group, which is suboptimal since we are using a python loop to index $k$ different times instead of vectorizing the operation:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_original</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">stack</span><span class="p">([</span><span class="n">data</span><span class="p">[</span><span class="n">labels</span><span class="o">==</span><span class="n">i</span><span class="p">].</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">)])</span>
<span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span> <span class="c1"># dummy labels
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_original</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 1.15 ms per loop
</pre>
</div>
<p>In terms of time complexity, creating a boolean mask takes $\mathcal O(n)$ time, due to <code class="language-plaintext highlighter-rouge">labels</code> having <code class="language-plaintext highlighter-rouge">n</code> elements.
Then, selecting the corresponding elements in <code class="language-plaintext highlighter-rouge">data</code> and performing the mean takes $\mathcal O(nd)$ time in the worst case (since at worst, <code class="language-plaintext highlighter-rouge">n</code> elements will be selected).
This operation happens <code class="language-plaintext highlighter-rouge">k</code> times in total, leading to a time complexity of $\mathcal O(k(nd+n)) = \mathcal O(ndk)$.</p>
<p>We can remove the loop and vectorize computing the boolean mask.
Concretely, we’ll need a matrix of shape <code class="language-plaintext highlighter-rouge">(n, k)</code>, where column <code class="language-plaintext highlighter-rouge">i</code> has 1s in rows corresponding to data points in cluster <code class="language-plaintext highlighter-rouge">i</code> (and 0s elsewhere).
This means each row is filled with 0s except for a single spot spot (since each data point belongs to one cluster).
We’ll call this a matrix of one <em>one-hot vectors</em> (terminology from machine learning), and is explained in more detail in the <a href="https://nicholasvadivelu.com/2021/02/16/groupby-from-scratch/">group-by post</a>.
We’ll use two different approaches to compute this matrix, both of which are benchmarked further in the appendix.
The time complexity for both approaches $\mathcal O(nk)$.</p>
<p>We can use this one-hot matrix to perform a <em>masked-mean</em>.
First, we use explicit broadcasting to replicate data and one-hot matrix into a <code class="language-plaintext highlighter-rouge">(n, k, d)</code> array (remember, no extra memory is needed, NumPy only pretends that the original matrices are duplicated).
Then, we compute a mean along the first axis, only considering values where the mask value (i.e. broadcasted one-hot matrix) is 1.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_masked_mean</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">):</span>
<span class="n">onehot_matrix</span> <span class="o">=</span> <span class="n">labels</span><span class="p">[:,</span><span class="bp">None</span><span class="p">]</span> <span class="o">==</span> <span class="n">centroid_labels</span> <span class="c1"># (n, k)
</span> <span class="n">b_data</span><span class="p">,</span> <span class="n">b_oh</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">broadcast_arrays</span><span class="p">(</span> <span class="c1"># (n, k, d), (n, k, d)
</span> <span class="n">data</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">],</span> <span class="n">onehot_matrix</span><span class="p">[:,</span> <span class="p">:,</span> <span class="bp">None</span><span class="p">])</span>
<span class="k">return</span> <span class="n">b_data</span><span class="p">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">where</span><span class="o">=</span><span class="n">b_oh</span><span class="p">)</span> <span class="c1"># (k, d)
</span>
<span class="n">centroid_labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">int32</span><span class="p">)</span> <span class="c1"># (k, )
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_masked_mean</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 loops, best of 5: 9.78 ms per loop
</pre>
</div>
<p>The <code class="language-plaintext highlighter-rouge">mean</code> method still has to iterate over the entire <code class="language-plaintext highlighter-rouge">(n, k, d)</code> array when accumulating values, resulting in a time complexity of $\mathcal O(nk + nkd) = \mathcal O(nkd)$</p>
<p>Despite eliminating the loop through vectorization, this approach is <em>slower</em> than our initial implementation.
Based on my experience, the <code class="language-plaintext highlighter-rouge">where</code> argument for NumPy reductions is not well optimized.</p>
<p>Our upcoming approaches sum up the vectors in each group, then divide by the number of elements in each group.
Recall from the group-by post, that <code class="language-plaintext highlighter-rouge">np.bincount</code> is the fastest way to compute the number of the elements in each group.
Also from that post, given the one-hot matrix, summing within each groups can be represented as a matrix multiplication, which we’ll do via <code class="language-plaintext highlighter-rouge">np.dot</code>:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_dense_matmul</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">identity</span><span class="p">):</span>
<span class="n">onehot_labels</span> <span class="o">=</span> <span class="n">identity</span><span class="p">[</span><span class="n">labels</span><span class="p">]</span> <span class="c1"># (n, k)
</span> <span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="c1"># (k, 1)
</span> <span class="n">group_sums</span> <span class="o">=</span> <span class="n">onehot_labels</span><span class="p">.</span><span class="n">T</span><span class="p">.</span><span class="n">dot</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="c1"># (k, d)
</span> <span class="c1"># equivalently,
</span> <span class="c1"># group_sums = np.einsum('nd,nk->kd', data, onehot_labels)
</span> <span class="k">return</span> <span class="n">group_sums</span> <span class="o">/</span> <span class="n">group_counts</span>
<span class="n">identity</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">eye</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="c1"># (k, k)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_dense_matmul</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">identity</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 1.03 ms per loop
</pre>
</div>
<p>The time complexity of dense matrix multiplication between a <code class="language-plaintext highlighter-rouge">(n, d)</code> and <code class="language-plaintext highlighter-rouge">(k, d)</code> matrix is $\mathcal O(nkd)$. The <code class="language-plaintext highlighter-rouge">group_counts</code> allocates an array of size <code class="language-plaintext highlighter-rouge">k</code>, then simply does an increment for each value of <code class="language-plaintext highlighter-rouge">labels</code>, leading to a complexity of $\mathcal O(n + k)$. Combined with the construction of the <code class="language-plaintext highlighter-rouge">onehot_labels</code>, the overall complexity is $\mathcal O(nkd + (n+k) + nk) = \mathcal O(nkd)$.</p>
<p>However, this method does more work than the masked mean, since we are doing a matrix multiplication instead of a masked sum and divide.
A lot of these sums and products are redundant as they’re with 0s, since our one-hot matrix has a sparse structure (and gets increasingly sparse as <code class="language-plaintext highlighter-rouge">k</code> grows larger).
For our current input sizes, this method still beats the innefficient masked mean, but is slower than our original.</p>
<p>We can avoid avoid constructing the dense one-hot matrix using <code class="language-plaintext highlighter-rouge">scipy.sparse</code>.</p>
<h3 id="sparse-matrices">Sparse Matrices</h3>
<p>The one-hot matrix has a sparse structure–only one non-zero value per row–which we’ll leverage to construct the matrix faster and do less work during the matrix multiplication.</p>
<p>Compressed Sparse Row (CSR) and Compressed Sparse Column (CSC) matrices are two formats which are designed for fast arithmetic (e.g. matrix multiplication).
The <a href="https://docs.scipy.org/doc/scipy/reference/sparse.html">SciPy documentation</a> explains how they work.
Practically speaking, CSR is more space-efficient for matrices with fewer rows; CSC for matrices with fewer columns.
It’s nearly impossible to reason about which will be more time-efficient, so you should always benchmark to check.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">sparse</span>
<span class="k">def</span> <span class="nf">update_step_csr</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">ones_vec</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">):</span>
<span class="c1"># notice this onehot matrix is the transpose of our original
</span> <span class="n">onehot_matrix</span> <span class="o">=</span> <span class="n">sparse</span><span class="p">.</span><span class="n">csr_matrix</span><span class="p">(</span>
<span class="c1"># constructor: (values, (row_indices, column_indices))
</span> <span class="p">(</span><span class="n">ones_vec</span><span class="p">,</span> <span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">)),</span> <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>
<span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="c1"># (k, 1)
</span> <span class="k">return</span> <span class="n">onehot_matrix</span><span class="p">.</span><span class="n">dot</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">/</span> <span class="n">group_counts</span>
<span class="n">ones_vec</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">ones_like</span><span class="p">(</span><span class="n">labels</span><span class="p">)</span> <span class="c1"># (n,)
</span><span class="n">column_inds</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="c1"># (n,)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_csr</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">ones_vec</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 514 µs per loop
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_csc</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">ones_vec</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">):</span>
<span class="c1"># constructor: (values, (row_indices, column_indices))
</span> <span class="n">onehot_matrix</span> <span class="o">=</span> <span class="n">sparse</span><span class="p">.</span><span class="n">csc_matrix</span><span class="p">(</span>
<span class="p">(</span><span class="n">ones_vec</span><span class="p">,</span> <span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">)),</span> <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>
<span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="c1"># (k, 1)
</span> <span class="k">return</span> <span class="n">onehot_matrix</span><span class="p">.</span><span class="n">dot</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">/</span> <span class="n">group_counts</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_csc</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">ones_vec</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 491 µs per loop
</pre>
</div>
<p>For the sake of analysis, we’ll ignore the time needed to construct these sparse matrices (spoiler: it’s negligible compared to the rest).
The sparse matrix multiplication is more efficient than the dense: it only multiplies the non-zero values, which we have <code class="language-plaintext highlighter-rouge">n</code> of. We must multiply with all the values in our dense data matrix, and accumulate the result in an <code class="language-plaintext highlighter-rouge">(k, d)</code> matrix, resulting in a time complexity of $\mathcal O(n + nd + kd) + \mathcal O(d(n+k))$.
Combined with the <code class="language-plaintext highlighter-rouge">group_counts</code> computation, this results in a time complexity of $\mathcal O(d(n+k) + (n+k)) = \mathcal O (d(n+k))$.</p>
<p>This is <em>much</em> better than our previous approaches, but we still have some wasted work, since we are doing a matrix multiplication instead of a straight sum.
Our upcoming approaches will avoid boolean masks altogether.</p>
<h3 id="update_step-without-boolean-masks"><code class="language-plaintext highlighter-rouge">update_step</code> without boolean masks</h3>
<p><em>Unbuffered addition</em> is a simple way to sum values in each group, and works for vector-valued sums (unlike <code class="language-plaintext highlighter-rouge">np.bincount</code>).
Recall from the group-by post that <code class="language-plaintext highlighter-rouge">np.add.at</code> essentially does <code class="language-plaintext highlighter-rouge">array[indices] += values</code>, except <code class="language-plaintext highlighter-rouge">indices</code> is allowed to have duplicates.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_add_at</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
<span class="n">_</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">shape</span>
<span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="c1"># (k, 1)
</span> <span class="n">group_sums</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="n">d</span><span class="p">))</span> <span class="c1"># (k, d)
</span> <span class="n">np</span><span class="p">.</span><span class="n">add</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">group_sums</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="c1"># unbuffered sum
</span> <span class="k">return</span> <span class="n">group_sums</span> <span class="o">/</span> <span class="n">group_counts</span> <span class="c1"># (k, d)
</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_add_at</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 loops, best of 5: 9.9 ms per loop
</pre>
</div>
<p>As we saw before, creating <code class="language-plaintext highlighter-rouge">group_counts</code> takes $\mathcal O(n + k)$ time.
Creating the <code class="language-plaintext highlighter-rouge">group_sums</code> takes $\mathcal O(kd)$ time, then we sum <code class="language-plaintext highlighter-rouge">n</code> vectors of size <code class="language-plaintext highlighter-rouge">d</code>, which takes $\mathcal O(nd)$ (the index select takes constant time).
Adding these up, we get a time complexity of $\mathcal O((n+k) + kd + nd) = \mathcal O(d(n+k))$.</p>
<p>Unfortunately, as seen in the group-by post, unbuffered addition in NumPy is comparatively slow, making this method the second slowest we’ve tried so far.</p>
<p><code class="language-plaintext highlighter-rouge">np.bincount</code> will do the exact same operation much faster for scalars.
Recall that using <code class="language-plaintext highlighter-rouge">weights=data</code> lets us sum the groups in the data corresponding to the <code class="language-plaintext highlighter-rouge">labels</code>.
Not providing weights is equivalent to <code class="language-plaintext highlighter-rouge">weights=np.ones_like(labels)</code>, which we use to compute the <code class="language-plaintext highlighter-rouge">group_counts</code>.
We can use <code class="language-plaintext highlighter-rouge">np.apply_along_axis</code> to run <code class="language-plaintext highlighter-rouge">np.bincount</code> <code class="language-plaintext highlighter-rouge">d</code> times to average each dimension individually.
However, <code class="language-plaintext highlighter-rouge">np.apply_along_axis</code> uses a python for-loop in the backend, instead of actually vectorizing the operation.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_apply_bincount</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
<span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="c1"># (k, 1)
</span> <span class="n">fn</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">w</span><span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">weights</span><span class="o">=</span><span class="n">w</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">apply_along_axis</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="o">/</span> <span class="n">group_counts</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_apply_bincount</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 556 µs per loop
</pre>
</div>
<p>The <code class="language-plaintext highlighter-rouge">apply_along_axis</code> does this same operations for each dimension in<code class="language-plaintext highlighter-rouge">d</code>, leading to $\mathcal O(d(n+k))$ time.
With the <code class="language-plaintext highlighter-rouge">group_counts</code>, the total time complexity is $\mathcal O((n+k) + d(n+k)) = \mathcal O(d(n+k))$.</p>
<p>Although <code class="language-plaintext highlighter-rouge">np.apply_along_axis</code> is designed for convenience not speed, we observe a runtime improvement compared to our initial approaches.</p>
<p>Can we get rid of this Python loop altogether?</p>
<p>We currently have <code class="language-plaintext highlighter-rouge">k</code> bins: one for each centroid.
Then, we sum the elements for each centroid one dimension at a time.
To vectorize this operation and avoid the loop, we can instead pretend we have <code class="language-plaintext highlighter-rouge">k*d</code> groups.
Then, we can run <code class="language-plaintext highlighter-rouge">np.bincount</code> once on the flattened data, then reshape our result so we have <code class="language-plaintext highlighter-rouge">k</code> groups of dimension <code class="language-plaintext highlighter-rouge">d</code>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">update_step_flat_bincount</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">extended_labels</span><span class="p">):</span>
<span class="n">_</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">shape</span>
<span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)</span> <span class="c1"># (k,)
</span> <span class="n">label_matrix</span> <span class="o">=</span> <span class="n">extended_labels</span> <span class="o">+</span> <span class="n">labels</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="c1"># (n, d)
</span> <span class="n">group_sums</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span> <span class="c1"># (k*d,)
</span> <span class="n">label_matrix</span><span class="p">.</span><span class="n">ravel</span><span class="p">(),</span> <span class="n">weights</span><span class="o">=</span><span class="n">data</span><span class="p">.</span><span class="n">ravel</span><span class="p">(),</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="o">*</span><span class="n">d</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">group_sums</span><span class="p">.</span><span class="n">reshape</span><span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="n">k</span><span class="p">))</span> <span class="o">/</span> <span class="n">group_counts</span><span class="p">).</span><span class="n">T</span> <span class="c1"># (k, d)
</span>
<span class="n">extended_labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="n">start</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="n">d</span><span class="o">*</span><span class="n">k</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="n">k</span><span class="p">)</span> <span class="c1"># (d,)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">update_step_flat_bincount</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">labels</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">extended_labels</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 547 µs per loop
</pre>
</div>
<p>Constructing our <code class="language-plaintext highlighter-rouge">label_matrix</code> takes $\mathcal O(nd)$ time; <code class="language-plaintext highlighter-rouge">group_sums</code> takes $\mathcal O(nd + dk)$ time.
Combined with the <code class="language-plaintext highlighter-rouge">group_counts</code> computation, this takes $\mathcal O(nd + nd + dk + (n+k)) = \mathcal O(d(n+k))$ time.</p>
<p>Despite the same time complexity, we’re doing a non-trivial amount of extra work here: we need to generate the <code class="language-plaintext highlighter-rouge">label_matrix</code> of size <code class="language-plaintext highlighter-rouge">(n, d)</code>, which is why we don’t see a win over the Python-loop <code class="language-plaintext highlighter-rouge">apply_along_axis</code> variant.</p>
<h3 id="timing">Timing</h3>
<p>We’ve been comparing these approaches for one set of <code class="language-plaintext highlighter-rouge">n, d, k</code>, so let’s sweep these values.
For the below plot, we run each <code class="language-plaintext highlighter-rouge">n, d, k</code> triplet for 1000 iterations (with 95% confidence intervals, once again).</p>
<p><img src="/assets/images/posts/fast-k-means/update_cmp.svg#center" alt="" /></p>
<p>We can very clearly see the effect of the various time complexities at play here, as the $\mathcal O(nkd)$ approaches seem to scale much more poorly with respect to $k$ than the $\mathcal O(d(n+k)$ approaches.</p>
<p>It’s quite interesting that our initial, unvectorized implementation beats a few of our vectorized ones.
One possible explanation is that our mean is often computed over a comparatively smaller matrix for each group (due to boolean indexing one group at a time), while the vectorized approaches always scan over the full <code class="language-plaintext highlighter-rouge">(n, k, d)</code> array.
It’s also strange that the <code class="language-plaintext highlighter-rouge">dense_matmul</code> implementation varies so much as the size increases (despite the confidence intervals being quite tight).
This may be due to cache interactions.</p>
<p>Among the faster implementations, the CSR/CSC approaches are the best, with CSC being slightly better.
The bincount based approaches are faster at smaller dimensions, as they do less work (due to the lack of multiplication entirely) at the limit of <code class="language-plaintext highlighter-rouge">d=1</code>, while scaling poorly for larger <code class="language-plaintext highlighter-rouge">d</code>.</p>
<p>But this is only one view of the data, and we should investigate more closely how these methods interact with varying $k$ and $d$.
We’ll look closer at the bincount based approaches and CSC.</p>
<p><img src="/assets/images/posts/fast-k-means/update_step_hmap.svg#center" alt="" /></p>
<p>Note that the times in the heatmap have been multiplied by 10,000 to more easily display the timings.
As we had anticipated, the culprit in our slowdowns for both bincounts is indeed <code class="language-plaintext highlighter-rouge">d</code>, without much influence from <code class="language-plaintext highlighter-rouge">k</code>.</p>
<p>These results indicate that a <code class="language-plaintext highlighter-rouge">bincount</code> based approach may be more suitable for small <code class="language-plaintext highlighter-rouge">d</code>, while CSC will be superiour for larger <code class="language-plaintext highlighter-rouge">d</code>.</p>
<h2 id="putting-it-all-together">Putting it all together</h2>
<p>Based on our results, we can have two potential implementations for k-means, depending on whether we are dealing with high dimensional vectors or low:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kmeans_small_d</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">num_iter</span><span class="o">=</span><span class="mi">50</span><span class="p">):</span>
<span class="n">n</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">shape</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">replace</span><span class="o">=</span><span class="bp">False</span><span class="p">)]</span> <span class="c1"># (k, d)
</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_iter</span><span class="p">):</span>
<span class="c1"># ASSIGNMENT STEP
</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="o">-</span> <span class="n">centroids</span><span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="c1"># (n, k, d)
</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">'nkd,nkd->nk'</span><span class="p">,</span> <span class="n">diff</span><span class="p">,</span> <span class="n">diff</span><span class="p">).</span><span class="n">argmin</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># UPDATE STEP
</span> <span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span>
<span class="n">fn</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">w</span><span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">weights</span><span class="o">=</span><span class="n">w</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">apply_along_axis</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="o">/</span> <span class="n">group_counts</span>
<span class="k">return</span> <span class="n">centroids</span>
<span class="k">def</span> <span class="nf">kmeans_large_d</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">num_iter</span><span class="o">=</span><span class="mi">50</span><span class="p">):</span>
<span class="n">n</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">shape</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">replace</span><span class="o">=</span><span class="bp">False</span><span class="p">)]</span> <span class="c1"># (k, d)
</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_iter</span><span class="p">):</span>
<span class="c1"># ASSIGNMENT STEP
</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">data</span><span class="p">[:,</span> <span class="bp">None</span><span class="p">]</span> <span class="o">-</span> <span class="n">centroids</span><span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="c1"># (n, k, d)
</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">'nkd,nkd->nk'</span><span class="p">,</span> <span class="n">diff</span><span class="p">,</span> <span class="n">diff</span><span class="p">).</span><span class="n">argmin</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># UPDATE STEP
</span> <span class="n">onehot_labels</span> <span class="o">=</span> <span class="n">sparse</span><span class="p">.</span><span class="n">csc_matrix</span><span class="p">(</span>
<span class="p">(</span><span class="n">ones_vec</span><span class="p">,</span> <span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">column_inds</span><span class="p">)),</span> <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>
<span class="n">group_counts</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">k</span><span class="p">)[:,</span> <span class="bp">None</span><span class="p">]</span>
<span class="n">centroids</span> <span class="o">=</span> <span class="n">onehot_labels</span><span class="p">.</span><span class="n">dot</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">/</span> <span class="n">group_counts</span> <span class="c1"># (k, d)
</span>
<span class="k">return</span> <span class="n">centroids</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">kmeans_small_d</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1 loop, best of 5: 649 ms per loop
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">timeit</span> <span class="n">kmeans_large_d</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1 loop, best of 5: 553 ms per loop
</pre>
</div>
<p>We opted for the <code class="language-plaintext highlighter-rouge">apply_along_axis</code> solution over the <code class="language-plaintext highlighter-rouge">flat_bincount</code> solution due to its simplicity.
With these changes, we’re able to cut down the runtime from dozens of seconds to about half a second!</p>
<h2 id="takeaways">Takeaways</h2>
<p>Through this process, we’ve learned that the main priority when writing fast NumPy is to avoid loops and vectorize operations.
Sometimes, doing extra work with vectorization can be faster than doing less work with Python loops; however, as the problem scales, this becomes less true.
The only way to determine what will be fastest for your situation is to benchmark!</p>
<h2 id="appendix">Appendix</h2>
<p>Earlier, we chose different methods for creating one-hot matrices of booleans (for masking) vs floats (for multiplication), both of which are detailed in the <a href="https://nicholasvadivelu.com/2021/02/16/groupby-from-scratch/">group-by post</a>.
Here, we’ll show a detailed comparison of when each approach is suitable.</p>
<p>Below are the implementations:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">eye_bool</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">,</span> <span class="n">bool_identity</span><span class="p">):</span>
<span class="k">return</span> <span class="n">bool_identity</span><span class="p">[</span><span class="n">labels</span><span class="p">]</span> <span class="c1"># (n, k)
</span>
<span class="n">bool_identity</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">eye</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">bool</span><span class="p">)</span> <span class="c1"># (k, k)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">eye_bool</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">,</span> <span class="n">bool_identity</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
10000 loops, best of 5: 85.9 µs per loop
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">arange_bool</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">):</span>
<span class="k">return</span> <span class="n">labels</span><span class="p">[:,</span><span class="bp">None</span><span class="p">]</span> <span class="o">==</span> <span class="n">centroid_labels</span> <span class="c1"># (n, k)
</span>
<span class="o">%</span><span class="n">timeit</span> <span class="n">arange_bool</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
10000 loops, best of 5: 184 µs per loop
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">eye_float</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">float_identity</span><span class="p">):</span>
<span class="k">return</span> <span class="n">float_identity</span><span class="p">[</span><span class="n">labels</span><span class="p">]</span>
<span class="n">float_identity</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">eye</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span> <span class="c1"># (k, k)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">eye_float</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">float_identity</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
10000 loops, best of 5: 134 µs per loop
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">arange_float</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">,</span> <span class="n">out</span><span class="p">):</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">equal</span><span class="p">(</span><span class="n">labels</span><span class="p">[:,</span><span class="bp">None</span><span class="p">],</span> <span class="n">centroid_labels</span><span class="p">,</span> <span class="n">out</span><span class="o">=</span><span class="n">out</span><span class="p">)</span>
<span class="n">out</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">empty</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span> <span class="c1"># (n, k)
</span><span class="o">%</span><span class="n">timeit</span> <span class="n">arange_float</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">centroid_labels</span><span class="p">,</span> <span class="n">out</span><span class="o">=</span><span class="n">out</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1000 loops, best of 5: 308 µs per loop
</pre>
</div>
<p>For the <code class="language-plaintext highlighter-rouge">arange_float</code>, we use a pre-allocated output array to give it a fighting chance against <code class="language-plaintext highlighter-rouge">eye_float</code>, as otherwise, we need to materialize the array then make a copy to conver the dtype.
Generally, I avoid using output arrays like this, as it’s bug-prone and not idiomatic.</p>
<p>Let’s compare these implementations across various <code class="language-plaintext highlighter-rouge">n</code> and <code class="language-plaintext highlighter-rouge">k</code>:</p>
<p><img src="/assets/images/posts/fast-k-means/onehot_hmap.svg#center" alt="" /></p>
<p>Above, we plot the ratio between <code class="language-plaintext highlighter-rouge">arange</code> and <code class="language-plaintext highlighter-rouge">eye</code> for <code class="language-plaintext highlighter-rouge">float</code> and <code class="language-plaintext highlighter-rouge">bool</code>.
We see in general, <code class="language-plaintext highlighter-rouge">eye</code> has the advantage, except for small <code class="language-plaintext highlighter-rouge">k</code> for bool.</p>
<p>The <code class="language-plaintext highlighter-rouge">arange</code>-based approach needs to do a comparison <code class="language-plaintext highlighter-rouge">n*k</code> times, whereas the <code class="language-plaintext highlighter-rouge">eye</code> based approach is merely an index select.
<code class="language-plaintext highlighter-rouge">arange</code> only beats out <code class="language-plaintext highlighter-rouge">eye</code> at smaller <code class="language-plaintext highlighter-rouge">k</code> beecause populating the final array with the comparison result ends up being faster than copying over the corresponding row from the identity matrix.</p>Nicholas Vadivelunicholas.vadivelu@gmail.comRejection & Importance Sampling Explained in Code2021-03-09T00:00:00+00:002021-03-09T00:00:00+00:00https://nicholasvadivelu.com/2021/03/09/rejection-importance-sampling<center>
<a href="https://colab.research.google.com/github/n2cholas/dsc-workshops/blob/master/Bayesian_Data_Analysis/rejection_importance_sampling_demo.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a>
</center>
<p>Lecture 4 of <a href="https://avehtari.github.io/BDA_course_Aalto">Bayesian Data Analysis</a> by Aki Vehtari covered sampling techniques.
Essentially, we want to infer some properties of a (possibly unnormalized) density function $q$ (our target distribution) that we can’t sample directly from.
In this course, $q$ is usually is the product of our likelihood and prior, i.e., the unnormalized posterior.
Rejection sampling and importance sampling are techniques that allow us to transform observations from a proposal distribution $g$ (from which we can draw samples) into observations from our target distribution $q$.</p>
<p>In this post, we will look at how to implement these algorithms in practice.
This supplements the course content as well as the <a href="https://github.com/avehtari/BDA_py_demos/blob/master/demos_ch10/demo10_1.ipynb">demo</a>.
Our example objective is to estimate the variance of $q$.
Suppose we <em>could</em> sample from $q$ directly.
Then, given $n$ samples $\theta_1, \theta_2, …, \theta_n$, we would compute the sample variance $\hat \sigma^2$ via:</p>
\[\hat \mu = \frac{1}{n} \sum_{i=1}^n \theta_i\]
\[\hat \sigma^2 = \frac{1}{n} \sum_{i=1}^n (\theta_i - \hat \mu)^2\]
<p>For simplicity we’re using a <em>biased</em> estimator for the sample variance (to have an unbiased estimator, you’d need to divide by $n-1$ instead of $n$).
In code:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">stats</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="k">def</span> <span class="nf">estimate_variance</span><span class="p">(</span><span class="n">thetas</span><span class="p">):</span>
<span class="n">mu</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">(</span><span class="n">thetas</span><span class="p">)</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">((</span><span class="n">thetas</span> <span class="o">-</span> <span class="n">mu</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
</code></pre></div></div>
<p>But as mentioned, we don’t know how to sample from $q$.</p>
<h2 id="set-up">Set-up</h2>
<p>Before getting into the algorithms, we’ll set up some functions we need.</p>
<p>First, the (unnormalized) density for $q$.
We don’t care what the function is, only that we can evaluate it at various points.
So, we’ll use the same function Professor Vehtari provides in his <a href="https://github.com/avehtari/BDA_py_demos/blob/master/demos_ch10/demo10_1.ipynb">demo</a>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">q_density</span><span class="p">(</span><span class="n">theta</span><span class="p">):</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">([</span><span class="mf">1.1</span><span class="p">,</span> <span class="mf">1.3</span><span class="p">,</span><span class="o">-</span><span class="mf">0.1</span><span class="p">,</span><span class="o">-</span><span class="mf">0.7</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.4</span> <span class="p">,</span> <span class="mf">0.06</span><span class="p">,</span><span class="o">-</span><span class="mf">1.7</span><span class="p">,</span>
<span class="mf">1.7</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.7</span><span class="p">,</span> <span class="mf">1.6</span><span class="p">,</span><span class="o">-</span><span class="mf">2.06</span><span class="p">,</span><span class="o">-</span><span class="mf">0.74</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">,</span> <span class="mf">0.5</span> <span class="p">])</span>
<span class="k">return</span> <span class="n">stats</span><span class="p">.</span><span class="n">gaussian_kde</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">bw_method</span><span class="o">=</span><span class="mf">0.48</span><span class="p">).</span><span class="n">evaluate</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span>
</code></pre></div></div>
<p>Let’s plot it in the range $[-3, 3]$ to see how it looks:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">thetas</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linspace</span><span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">q_density</span><span class="p">(</span><span class="n">thetas</span><span class="p">))</span>
<span class="n">ax</span><span class="p">.</span><span class="nb">set</span><span class="p">(</span><span class="n">xlabel</span><span class="o">=</span><span class="sa">r</span><span class="s">'$\theta$'</span><span class="p">,</span> <span class="n">ylabel</span><span class="o">=</span><span class="sa">r</span><span class="s">'$q(\theta)$'</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot1.svg#center" alt="" /></p>
<p>Next, we need to choose our proposal distribution $g$.
In practice, it is tough to choose a good $g$, particularly in higher dimensions.
Since we’re working in one dimension, we can visualize our distribution to see that it’s roughly bell shaped, and so the normal distribution seems like a reasonable proposal distribution.
We’re cheating a little by stealing the parameters from the original demo—in practice this requires more work.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">g_density</span><span class="p">(</span><span class="n">theta</span><span class="p">):</span>
<span class="k">return</span> <span class="n">stats</span><span class="p">.</span><span class="n">norm</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.1</span><span class="p">).</span><span class="n">pdf</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span>
</code></pre></div></div>
<p>Plotting $g$ with our $q$:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">q_density</span><span class="p">(</span><span class="n">thetas</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="sa">r</span><span class="s">'$q(\theta)$'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">g_density</span><span class="p">(</span><span class="n">thetas</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="sa">r</span><span class="s">'$g(\theta)$'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nb">set</span><span class="p">(</span><span class="n">xlabel</span><span class="o">=</span><span class="sa">r</span><span class="s">'$\theta$'</span><span class="p">,</span> <span class="n">ylabel</span><span class="o">=</span><span class="sa">r</span><span class="s">'Density Value at $\theta$'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">legend</span><span class="p">()</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot2.svg#center" alt="" /></p>
<p>We also want to be able to sample from $g$:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">sample_from_g</span><span class="p">(</span><span class="n">n_samples</span><span class="p">):</span>
<span class="k">return</span> <span class="n">stats</span><span class="p">.</span><span class="n">norm</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.1</span><span class="p">).</span><span class="n">rvs</span><span class="p">(</span><span class="n">n_samples</span><span class="p">)</span>
<span class="n">g_samples</span> <span class="o">=</span> <span class="n">sample_from_g</span><span class="p">(</span><span class="mi">10_000</span><span class="p">)</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="c1"># Outline to improve visibility of faint points
</span><span class="n">ax</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">g_samples</span><span class="p">,</span> <span class="n">np</span><span class="p">.</span><span class="n">ones_like</span><span class="p">(</span><span class="n">g_samples</span><span class="p">),</span> <span class="n">s</span><span class="o">=</span><span class="mi">600</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s">'white'</span><span class="p">,</span> <span class="n">edgecolor</span><span class="o">=</span><span class="s">'#1f77b4'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">g_samples</span><span class="p">,</span> <span class="n">np</span><span class="p">.</span><span class="n">ones_like</span><span class="p">(</span><span class="n">g_samples</span><span class="p">),</span> <span class="n">s</span><span class="o">=</span><span class="mi">600</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.01</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">labelleft</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot3.png#center" alt="" /></p>
<p>We have a bunch of values from our sample, which we can see comes from our $g$ distribution through a histogram:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">hist</span><span class="p">(</span><span class="n">g_samples</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot4.svg#center" alt="" /></p>
<h2 id="rejection-sampling">Rejection Sampling</h2>
<p>If we use <code class="language-plaintext highlighter-rouge">estimate_variance</code> with <code class="language-plaintext highlighter-rouge">g_samples</code>, we’ll get an approximation of the variance of $g$ (which is $1.1^2 = 1.21$)</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">estimate_variance</span><span class="p">(</span><span class="n">g_samples</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1.1934573460327211
</pre>
</div>
<p>If we can transform <code class="language-plaintext highlighter-rouge">g_samples</code> into samples that follow the $q$ distribution, we could estimate $q$’s variance.
As we learned, in rejection sampling, we must first choose an $M$ such that $Mg(\theta) > q(\theta)$ for all $\theta$.
Let’s do this visually, since in our one dimensional case, this is easy:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">q_density</span><span class="p">(</span><span class="n">thetas</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="sa">r</span><span class="s">'$q(\theta)$'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">M</span> <span class="ow">in</span> <span class="p">[</span><span class="mf">1.</span><span class="p">,</span> <span class="mf">1.5</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">2.5</span><span class="p">,</span> <span class="mf">3.0</span><span class="p">]:</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">M</span><span class="o">*</span><span class="n">g_density</span><span class="p">(</span><span class="n">thetas</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="sa">f</span><span class="s">'$</span><span class="si">{</span><span class="n">M</span><span class="si">}</span><span class="s">g(</span><span class="se">\\</span><span class="s">theta)$'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nb">set</span><span class="p">(</span><span class="n">xlabel</span><span class="o">=</span><span class="sa">r</span><span class="s">'$\theta$'</span><span class="p">,</span> <span class="n">ylabel</span><span class="o">=</span><span class="sa">r</span><span class="s">'Density Value at $\theta$'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">legend</span><span class="p">()</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot5.svg#center" alt="" /></p>
<p>Looks like $M \approx 2.5$ is sufficient.</p>
<p>Recall the plot above gives us the <em>density</em> of our probability distribution, which roughly tells how likely it is to draw a sample from that area.
Since $g$ and $q$ have different densities, we want to essentially resample points that we drew from $g$ to better match $q$.
We do this by accepting some points and rejecting others.</p>
<p>If the density $q(\theta)$ is relatively large when $g(\theta)$ is relatively small, we should accept more points around that $\theta$.
If the density $q(\theta)$ is relatively small when $g(\theta)$ is relatively large, we should reject more points around that $\theta$.
The ratio $\frac{q(\theta)}{M g(\theta)}$ gives us this information.
We only need $M$ to ensure $Mg(\theta) > q(\theta)$ for all $\theta$, so $0 \le \frac{q(\theta)}{M g(\theta)} \le 1$, allowing the ratio to be used as the probability of acceptance.
Let’s encapsulate this in a function:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">M</span> <span class="o">=</span> <span class="mf">2.5</span>
<span class="k">def</span> <span class="nf">acceptance_probability</span><span class="p">(</span><span class="n">theta</span><span class="p">):</span>
<span class="k">return</span> <span class="n">q_density</span><span class="p">(</span><span class="n">theta</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">M</span><span class="o">*</span><span class="n">g_density</span><span class="p">(</span><span class="n">theta</span><span class="p">))</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">thetas</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linspace</span><span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">acceptance_probability</span><span class="p">(</span><span class="n">thetas</span><span class="p">))</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot6.svg#center" alt="" /></p>
<p>We observe we have a higher chance of accepting points near the tails, since $q$ has more density in the tails compared to $g$.
Let’s look at the acceptance probability of each individual point in our sample:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">acceptance_probabilities</span> <span class="o">=</span> <span class="n">acceptance_probability</span><span class="p">(</span><span class="n">g_samples</span><span class="p">)</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">g_samples</span><span class="p">,</span> <span class="n">acceptance_probabilities</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">g_samples</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span> <span class="n">acceptance_probabilities</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span> <span class="n">c</span><span class="o">=</span><span class="s">'red'</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot7.svg#center" alt="" /></p>
<p>To pull one example, sample 0.6045 (in red) has an acceptance probability of 41.89%.
Also, as expected, this has the same shape as the previous plot, since we’re showing the same function with our samples as inputs instead of arbitrary values.</p>
<p>Now, onto the actual rejection sampling.
To randomly accept and reject points based on their probability, we’ll draw a (uniformly) random number between 0 and 1 for each sample.
If this draw is less than the acceptance probability, we’ll keep the point, otherwise, we’ll get reject the point:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rand_01</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="nb">len</span><span class="p">(</span><span class="n">g_samples</span><span class="p">))</span>
<span class="n">to_keep</span> <span class="o">=</span> <span class="n">rand_01</span> <span class="o"><</span> <span class="n">acceptance_probabilities</span>
<span class="n">to_keep</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([False, False, False, ..., False, True, True])
</pre>
</div>
<p>The array is <code class="language-plaintext highlighter-rouge">True</code> for the indices we’ll keep and <code class="language-plaintext highlighter-rouge">False</code> for the ones we reject.
We’ll use <em>boolean masking</em> to extract the points we’re accepting from our <code class="language-plaintext highlighter-rouge">g_samples</code> array:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">q_samples</span> <span class="o">=</span> <span class="n">g_samples</span><span class="p">[</span><span class="n">to_keep</span><span class="p">]</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Original number of samples: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">g_samples</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Number of accepted samples: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">q_samples</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Original number of samples: 10000
Number of accepted samples: 3992
</pre>
</div>
<p>We can see that in our case, rejection sampling was pretty inefficient—we threw away a whole bunch of points.
Our <em>effective sample size</em> is only 3958, which we can improve slightly by using a smaller $M$ (while still maintaining our inequality).</p>
<p>Now, we can use those samples to get the variance of $q$:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">estimate_variance</span><span class="p">(</span><span class="n">q_samples</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1.3519654308471265
</pre>
</div>
<h2 id="importance-sampling">Importance Sampling</h2>
<p>It can be challenging to find an efficient $g$ and $M$ such that $Mg(\theta) > q(\theta)$ for all $\theta$.
Since $Mg(\theta)$ will likely be quite different from $q(\theta)$, we’ll end up rejecting a lot of points.</p>
<p>Importance sampling improves this with one key observation: often, the property of interest is an expectation.
If we have samples from $q$, we could just average those samples to estimate this property (for the variance, we average $(\theta_i - \hat \mu)^2$).
If we have samples from $g$, we can do a <em>weighted average</em> where we downweight points that would be less likely to be sampled from $q$ (compared to $g$), and upweight points that would be more likely to be sampled from $q$ (compared to $g$).</p>
<p>These weights come from the ratio $\frac{q(\theta)}{g(\theta)}$:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">weights</span> <span class="o">=</span> <span class="n">q_density</span><span class="p">(</span><span class="n">g_samples</span><span class="p">)</span><span class="o">/</span><span class="n">g_density</span><span class="p">(</span><span class="n">g_samples</span><span class="p">)</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">g_samples</span><span class="p">,</span> <span class="n">weights</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/rejection-importance-sampling/plot8.svg#center" alt="" /></p>
<p>As we can see, the weights are just a scaled version of our rejection probabilities!
We can use these weights along with <code class="language-plaintext highlighter-rouge">g_samples</code> to compute the variance of $q$ by using a weighted mean instead of a normal mean:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">estimate_variance2</span><span class="p">(</span><span class="n">thetas</span><span class="p">,</span> <span class="n">weights</span><span class="p">):</span>
<span class="n">normalizing_val</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
<span class="n">mu</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="o">*</span><span class="n">thetas</span><span class="p">)</span> <span class="o">/</span> <span class="n">normalizing_val</span>
<span class="c1"># Below, we are doing E[(\theta-\mu)^2].
</span> <span class="c1"># Want to weight each item in the average, not each \theta_i.
</span> <span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="o">*</span><span class="p">(</span><span class="n">thetas</span> <span class="o">-</span> <span class="n">mu</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span> <span class="o">/</span> <span class="n">normalizing_val</span>
</code></pre></div></div>
<p>Notice this function with a weights of all 1s is the same as our original <code class="language-plaintext highlighter-rouge">estimate_variance</code>.
To check that, let’s estimate the variance of $g$ from the sample:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">estimate_variance2</span><span class="p">(</span><span class="n">g_samples</span><span class="p">,</span> <span class="n">np</span><span class="p">.</span><span class="n">ones_like</span><span class="p">(</span><span class="n">g_samples</span><span class="p">))</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1.1934573460327211
</pre>
</div>
<p>Now, let’s estimate the variance of our $q$ using these importance weights:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">estimate_variance2</span><span class="p">(</span><span class="n">g_samples</span><span class="p">,</span> <span class="n">weights</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
1.3422838900127976
</pre>
</div>
<p>Nice, we get (approximately) the same answer!</p>
<p>We can compute the <em>effective sample size</em> for importance sampling using this formula:</p>
\[\tilde w_i = \frac{w_i}{\sum_{j=1}^n w_j}\]
\[n_{ESS} = \frac{1}{\sum_{i=1}^n \tilde w_i^2}\]
<p>$\tilde w_i$ is the normalized version of $w_i$ (so $\sum_{i=1}^n \tilde w_i = 1$).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">normalized_weights</span> <span class="o">=</span> <span class="n">weights</span> <span class="o">/</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
<span class="n">n_ess</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">/</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">normalized_weights</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="n">n_ess</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
9382.334536341743
</pre>
</div>
<p>Our effective sample size is much better than with rejection sampling, since $g$ was pretty similar to $q$ everywhere (i.e. was a good proposal distribution).</p>Nicholas Vadivelunicholas.vadivelu@gmail.comGroupby-by From Scratch “Part 2”2021-02-16T00:00:00+00:002021-02-16T00:00:00+00:00https://nicholasvadivelu.com/2021/02/16/groupby-from-scratch<p>The group-by (or split-apply-combine) pattern, illustrated below, is ubiquitous
in data analysis. Essentially, you have data with predefined groups and want to
compute some summarizing statistics for each of those groups. For example,
suppose you have a set of High School students and want to estimate the average
height by grade. You would need to <em>split</em> the dataset by grade, <em>apply</em> the
mean operation to each group, then <em>combine</em> the means of all the groups
together. The figure below is from the <a href="https://github.com/jakevdp/PythonDataScienceHandbook">Python Data Science
Handbook</a>.</p>
<p><img src="/assets/images/posts/groupby/split-apply-combine.svg#center" alt="" /></p>
<p>In Python, the Pandas DataFrame library provides a fast, general implementation
of this algorithm. Jake VanderPlas wrote an excellent <a href="https://jakevdp.github.io/blog/2017/03/22/group-by-from-scratch/">blog
post</a> looking
at implementing this algorithm from scratch using NumPy (and SciPy). He
benchmarks the various approaches to help build intuition about writing fast
NumPy code. This post extends that one (which is why this post is labelled
“Part 2”), so please read Jake’s first then come back here.</p>
<p>Jake looks at the general case where you want to compute a sum within each
group, then return the results as a Python dictionary. The keys for the groups
can be any hashable type (strings, integers, etc.). In this post, I want to
relax a few of those requirements to optimize the implementations and see how
the results differ. Those relaxations are:</p>
<ol>
<li>The return value does not have to be a dictionary. It can be any type you
can index into using a key to retrieve the result (e.g. a list or
array).</li>
<li>The inputs are always NumPy arrays.</li>
<li>The keys are integers from 0 to $k$.</li>
<li>The maximum key, $k$, is known in advance.</li>
</ol>
<p>(1) seems reasonable, and should save us some time since we can avoid
converting the container types. (2) is realistic, since you almost always
want to manipulate numeric data in NumPy arrays instead of Python lists. (3) is
fine since we can always map our arbitrary labels to integers in advance. (4)
seems restrictive, but in practice, you often know how many groups you have in
your data. For the High School students example, you know there are 4 grades
(at least in Canada) apriori. If you are using a group-by to perform
unsupervised clustering, many algorithms require you to decide the number of
clusters in advance.</p>
<p>We’ll see that these relaxations allow us to simplify the implementations and
improve performance.</p>
<p>The rest of this post is structured as follows. First, we update the Jake’s
implementations according to our new constraints. The pandas/Python
implementations see very little change, while the NumPy based solutions see large
improvements. We do some big-O time complexity analysis to understand where we
gain efficiency. Next, we show some new implementations that these
relaxations afford us and go into more detail about these (as they’re not in
Jake’s post). Finally, we benchmark these implementations to see if the
conclusions from our analysis hold in practice.</p>
<p>For a quick reference, here are quicklinks to each updated implementation:</p>
<ol>
<li><a href="#pandas">Pandas</a></li>
<li><a href="#dict">Dictionary</a></li>
<li><a href="#masking">Masking</a></li>
<li><a href="#bincount"><code class="language-plaintext highlighter-rouge">np.bincount</code></a></li>
<li><a href="#sparse">Sparse</a></li>
<li><a href="#arange"><code class="language-plaintext highlighter-rouge">np.arange</code></a></li>
<li><a href="#eye"><code class="language-plaintext highlighter-rouge">np.eye</code></a></li>
<li><a href="#ndimage"><code class="language-plaintext highlighter-rouge">scipy.ndimage.sum</code></a></li>
<li><a href="#at"><code class="language-plaintext highlighter-rouge">np.add.at</code></a></li>
</ol>
<p>All the code is available in
<a href="https://colab.research.google.com/drive/1X0tIA_MmYVQVo--6SVa90mcnAMa55Bm1?usp=sharing">this</a>
Colab. It’s is similar to Jake’s, except we use <code class="language-plaintext highlighter-rouge">time.perf_counter()</code> to time,
<code class="language-plaintext highlighter-rouge">seaborn</code> to plot, and include 95% confidence bands in the line-plots.
Notably, the data distributions are the same.</p>
<h2 id="updated-implementations">Updated Implementations</h2>
<p>We use the following arrays as our example data:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="n">keys</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">asarray</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">])</span>
<span class="n">vals</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">asarray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">])</span>
<span class="n">max_key</span> <span class="o">=</span> <span class="n">keys</span><span class="p">.</span><span class="nb">max</span><span class="p">()</span>
</code></pre></div></div>
<p>This is the same as Jake’s running example, except our keys are integers and we
pre-compute the max key.</p>
<h3 id="non-numpy-approaches">Non-NumPy Approaches</h3>
<p>Our non-NumPy approaches don’t benefit much from our updated rules. First, the
most idiomatic and common solution in Python: Pandas.</p>
<p><a name="pandas"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="k">def</span> <span class="nf">pandas_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">pd</span><span class="p">.</span><span class="n">Series</span><span class="p">(</span><span class="n">vals</span><span class="p">).</span><span class="n">groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">).</span><span class="nb">sum</span><span class="p">()</span>
<span class="n">pandas_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
0 5
1 7
2 9
dtype: int64
</pre>
</div>
<p>The code is nearly identical, except we remove the <code class="language-plaintext highlighter-rouge">.to_dict()</code>, so the result
is a Pandas <code class="language-plaintext highlighter-rouge">Series</code>.</p>
<p>Since we know that the keys are from 0 to <code class="language-plaintext highlighter-rouge">max_key</code> in advance, we don’t have
to use a <code class="language-plaintext highlighter-rouge">defaultdict</code> for the dictionary-based approach, and can instead
prepopulate with 0s (shown below). In the end, we’ll see this doesn’t make a
big difference in performance.</p>
<p><a name="dict"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">dict_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">count</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)}</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">):</span>
<span class="n">count</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">+=</span> <span class="n">val</span>
<span class="k">return</span> <span class="n">count</span>
<span class="n">dict_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
{0: 5, 1: 7, 2: 9}
</pre>
</div>
<p>The itertools implementaton does not change, so I excluded the code (it’s in
Jake’s post).</p>
<h3 id="numpy-based-approaches">NumPy-based Approaches</h3>
<p>The additional information allows us to improve the <em>asymptotic behaviour</em> of
these NumPy-based approaches. That is, the behaviour as the dataset size ($n$)
and number of groups ($k$) grows large. This post assumes you’re familiar with
this concept,
<a href="https://www.freecodecamp.org/news/big-o-notation-simply-explained-with-illustrations-and-video-87d5a71c0174/">here</a>
is a great explanation if you’re not.</p>
<p>In the original problem, all these implementations require <code class="language-plaintext highlighter-rouge">np.unique</code> in
order to determine the keys. <code class="language-plaintext highlighter-rouge">np.unique</code> sorts the data, which is an $O(n \log
n)$ operation, where $n$ is the length of the dataset. Knowing our keys are 0
to $k$ where $k$ is known in advance allows us avoid this sort to save time.</p>
<p><a name="masking"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">masking_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">vals</span><span class="p">[</span><span class="n">keys</span> <span class="o">==</span> <span class="n">key</span><span class="p">].</span><span class="nb">sum</span><span class="p">()</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)]</span>
<span class="n">masking_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
[5, 7, 9]
</pre>
</div>
<p>Every boolean mask computation takes $O(n)$ time, which we do for each key,
resulting in $O(nk)$ time. This is more efficient than the original
implementation, which requires $O(n \log n + nk)$ time due to the sort.</p>
<p>The other small improvement is constructing a <code class="language-plaintext highlighter-rouge">list</code> instead of a <code class="language-plaintext highlighter-rouge">dict</code> due
to our keys being integer from 0 to <code class="language-plaintext highlighter-rouge">max_key</code>.</p>
<p>The <code class="language-plaintext highlighter-rouge">np.bincount</code> implementation becomes very sleek:</p>
<p><a name="bincount"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">bincount_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">bincount</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">weights</span><span class="o">=</span><span class="n">vals</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
<span class="n">bincount_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([5., 7., 9.])
</pre>
</div>
<p>Since we have the <code class="language-plaintext highlighter-rouge">max_key</code>, we can tell bincount how much space to
pre-allocate for the array (via <code class="language-plaintext highlighter-rouge">minlength</code>), which saves time on potential
array resizing. This approach only takes $O(n)$ time, since under the hood, the
function just iterates through the array once and adds each value to the
appropriate bucket.</p>
<p>For the sparse implementation, we again we save time by skipping <code class="language-plaintext highlighter-rouge">np.unique</code>
(and conversion to <code class="language-plaintext highlighter-rouge">dict</code>).</p>
<p><a name="sparse"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">sparse</span>
<span class="k">def</span> <span class="nf">sparse_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">col</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">keys</span><span class="p">))</span>
<span class="n">mat</span> <span class="o">=</span> <span class="n">sparse</span><span class="p">.</span><span class="n">coo_matrix</span><span class="p">((</span><span class="n">vals</span><span class="p">,</span> <span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">col</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">mat</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">sparse_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
matrix([[5],
[7],
[9]])
</pre>
</div>
<p>Since the sparse representation essentially stores a key-value lookup, the
time complexity here is once again $O(n)$. If this was a dense matrix instead
of sparse (i.e. if we summed up the 0s that this sparse matrix hides), it would
be more expensive (which we’ll see below).</p>
<p>Our output seems a bit strange now, but this still gives us the desired
property of being able to index into it to get our sum:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="n">sparse_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
<span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
matrix([[5]])
</pre>
</div>
<p>But if you want an array, you can convert between NumPy matrices and arrays
without copying memory:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">np</span><span class="p">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">x</span><span class="p">).</span><span class="n">ravel</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([5, 7, 9])
</pre>
</div>
<h2 id="new-implementations">New Implementations</h2>
<p>The convenient properties of our keys afford us some alternative
implementations. We’ll cover these in more detail since they were not in Jake’s
post. First:</p>
<p><a name="arange"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">arange_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">):</span>
<span class="n">one_hot</span> <span class="o">=</span> <span class="n">keys</span> <span class="o">==</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)[:,</span><span class="bp">None</span><span class="p">]</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">dot</span><span class="p">(</span><span class="n">one_hot</span><span class="p">,</span> <span class="n">vals</span><span class="p">)</span>
<span class="n">arange_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([5, 7, 9])
</pre>
</div>
<p>Let’s break this one down. Conceptually, this is almost identical to the sparse
matrix approach. Instead of having integer keys, we convert to a “one hot”
representation (which you may be familiar with from other machine learning
tasks). Essentially, each label becomes a vector with <code class="language-plaintext highlighter-rouge">max_key</code> dimensions. All
the values of that vector are 0 except at the index of the label. For example,
if <code class="language-plaintext highlighter-rouge">max_key = 2</code> and our <code class="language-plaintext highlighter-rouge">key = 0</code>, our one hot vector would be <code class="language-plaintext highlighter-rouge">[1, 0, 0]</code> (1
only in the 0th position).</p>
<p>Note that <code class="language-plaintext highlighter-rouge">np.arange(max_key+1) = [0, 1, 2]</code>. If <code class="language-plaintext highlighter-rouge">key = 0</code>, then <code class="language-plaintext highlighter-rouge">(key == [0, 1,
2]) = [True, False, False]</code>, which can be interpreted as <code class="language-plaintext highlighter-rouge">[1, 0, 0]</code>, which is
our one hot representation. We want to obtain the one hot representation for
every key in our collection, which we achieve using a
<a href="https://numpy.org/devdocs/user/theory.broadcasting.html">broadcasting</a> trick.
The documentation linked provides an excellent explanation which I highly
encourage you read. We use this trick to get:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">one_hot</span> <span class="o">=</span> <span class="n">keys</span> <span class="o">==</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)[:,</span><span class="bp">None</span><span class="p">]</span>
<span class="n">one_hot</span><span class="p">.</span><span class="n">astype</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([[1, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 1]])
</pre>
</div>
<p>Here, each column in our matrix represents the one hot representation of each
key. Now, when we use <code class="language-plaintext highlighter-rouge">np.dot</code>, we are computing the inner product between each
row of this matrix and the entire values vector. This gives us the sum within
each group (I’ll leave it as an exercise to you to verify that). It’s
essentially the same as the summation in the sparse COO matrix case.</p>
<p>In terms of time complexity, the one_hot computation compares every value in
our data to every potential key, resulting in $O(nk)$ time. The matrix
multiplication is $O(n)$ for each row (since you’re multiplying $n$ values and
summing), so it’s a total of $O(nk)$ for the entire dot product. This result in
a total running time of $O(nk+nk) = O(nk)$.</p>
<p>Our next implementation leverages a one hot representation as well:</p>
<p><a name="eye"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">eye_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">):</span>
<span class="n">one_hot</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">eye</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)[</span><span class="n">keys</span><span class="p">]</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">dot</span><span class="p">(</span><span class="n">one_hot</span><span class="p">.</span><span class="n">T</span><span class="p">,</span> <span class="n">vals</span><span class="p">)</span>
<span class="n">eye_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<p>Here, we compute the identity matrix using <code class="language-plaintext highlighter-rouge">np.eye</code>. We know row $i$ of this
matrix is zero everywhere but the $i$th column, which is precisely our one hot
representation. We use <a href="https://numpy.org/doc/stable/reference/arrays.indexing.html#advanced-indexing">advanced
indexing</a>
to extract the row corresponding to each label. Concretely:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">np</span><span class="p">.</span><span class="n">eye</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
</pre>
</div>
<p>Recall our keys are <code class="language-plaintext highlighter-rouge">[0, 1, 2, 0, 1, 2]</code>. With advanced indexing:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">np</span><span class="p">.</span><span class="n">eye</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)[</span><span class="n">keys</span><span class="p">]</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
</pre>
</div>
<p>This matrix is the transpose of what we had with <code class="language-plaintext highlighter-rouge">arange_groupby</code>, which is why
we transpose it before applying the dot product.</p>
<p>The time complexity is the same as the <code class="language-plaintext highlighter-rouge">arange</code> case. The advanced indexing
hides some of the operations, but you still have to materialize $nk$ values, then do the same
multiplication.</p>
<p>Our next implementation leverages unbuffered operations. Before showing it,
consider the following:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">incorrect_at_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
<span class="n">s</span><span class="p">[</span><span class="n">keys</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vals</span>
<span class="k">return</span> <span class="n">s</span>
<span class="n">incorrect_at_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([4., 5., 6.])
</pre>
</div>
<p>We used advanced indexing to pull out the right position in <code class="language-plaintext highlighter-rouge">s</code> depending on
the key, then added the corresponding item in <code class="language-plaintext highlighter-rouge">vals</code> to it. The problem is,
this is a buffered operation, which means the array is not updated
sequentially, so only the last update per index is observed. Since the last
occurence of 0, 1, and 2 in <code class="language-plaintext highlighter-rouge">keys</code> correspond to 4, 5, and 6 in <code class="language-plaintext highlighter-rouge">vals</code>, those
are the values we see. We can leverage
<a href="https://numpy.org/doc/stable/reference/generated/numpy.ufunc.at.html"><code class="language-plaintext highlighter-rouge">np.add.at</code></a>
to do this same operation in an <em>unbuffered</em> manner, which means each occurence
will accumulate:</p>
<p><a name="at"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">at_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
<span class="n">np</span><span class="p">.</span><span class="n">add</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">)</span>
<span class="k">return</span> <span class="n">s</span>
<span class="n">at_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([5., 7., 9.])
</pre>
</div>
<p>Finally, we can use another built-in function for performing a group-by, this
time in SciPy:</p>
<p><a name="ndimage"></a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">ndimage</span>
<span class="k">def</span> <span class="nf">ndimage_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">):</span>
<span class="k">return</span> <span class="n">ndimage</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">vals</span><span class="p">,</span> <span class="n">labels</span><span class="o">=</span><span class="n">keys</span><span class="p">,</span>
<span class="n">index</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="n">max_key</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span>
<span class="n">ndimage_groupby</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">max_key</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([5., 7., 9.])
</pre>
</div>
<p>This method is implemented using <code class="language-plaintext highlighter-rouge">np.bincount</code> under the hood, and thus will be
strictly slower (due to additional work to account for multidimensional
inputs). Thus, it will not be included in our benchmarks below.</p>
<h2 id="timings">Timings</h2>
<p>The timings were measured in Python 3.8.5 on an Intel i5-8265U CPU @ 1.60GHz
with 8gb of RAM on Ubuntu 20.04. For a baseline, below are timings of the
implementations provided in Jake’s blog post:</p>
<p><img src="/assets/images/posts/groupby/original_timings.svg#center" alt="" /></p>
<p>The colored bands around the lines are 95% confidence intervals (for most of
the implementations it’s invisible). Notice both axes are log. As shown in
Jake’s post, the Pandas implementation really starts to shine as we increase
the dataset size. At smaller sizes, the NumPy-based implementations all do
well, with the pure-NumPy (i.e. no Python <code class="language-plaintext highlighter-rouge">dict</code>s or <code class="language-plaintext highlighter-rouge">list</code>s) pulling ahead.
Masking slows down significantly with larger group sizes: at every iteration of
the masking loop (which is 1 per unique key), we have to evaluate a boolean
mask for the entire dataset, which gets expensive.</p>
<p>Below are timings for the updated implementations:</p>
<p><img src="/assets/images/posts/groupby/new_timings.svg#center" alt="" /></p>
<p>For the updated implementations, we observe some similar trends: the Pandas
implementation goes from slowest to among the fastest as our data size
increases, while the other increase with generally the same slope. When we
increase the number of groups, the masking and one-hot implementations suffer,
since their time complexity depends on the number of groups $k$.</p>
<p>The pure-numpy implementations benefit the most from our relaxations. All of
them used <code class="language-plaintext highlighter-rouge">np.unique</code>, and removing that call improved speed across the board
(as predicted by our big-O analysis). In particular, the <code class="language-plaintext highlighter-rouge">np.bincount</code>-based
implementation is now the fastest at all dataset and group sizes.</p>
<p>Below, we show the relative speed-up:</p>
<p><img src="/assets/images/posts/groupby/faster.svg#center" alt="" /></p>
<p>As we saw in the other two plots, the <code class="language-plaintext highlighter-rouge">np.unique</code>-based solutions saw the
biggest benefit (bincount, sparse, and masking), while the others saw
negligible improvements. This is expected: as the data size grows large,
container and key conversions are just small overheads compared to the large
computation.</p>
<p><br /></p>
<h2 id="code">Code</h2>
<p>All the code can be found in the Colab
<a href="https://colab.research.google.com/drive/1X0tIA_MmYVQVo--6SVa90mcnAMa55Bm1?usp=sharing">here</a>.
The main benchmarking functions are shown below:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">time_groupby</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">n_group</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">rseed</span><span class="o">=</span><span class="mi">754389</span><span class="p">,</span> <span class="n">n_iter</span><span class="o">=</span><span class="mi">500</span><span class="p">):</span>
<span class="n">times</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">empty</span><span class="p">(</span><span class="n">n_iter</span><span class="p">)</span>
<span class="n">rand</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">RandomState</span><span class="p">(</span><span class="n">rseed</span><span class="p">)</span>
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_iter</span><span class="p">):</span>
<span class="n">keys</span> <span class="o">=</span> <span class="n">rand</span><span class="p">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">n_group</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
<span class="n">vals</span> <span class="o">=</span> <span class="n">rand</span><span class="p">.</span><span class="n">rand</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
<span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="p">.</span><span class="n">perf_counter</span><span class="p">()</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">vals</span><span class="p">,</span> <span class="n">n_group</span><span class="p">)</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="p">.</span><span class="n">perf_counter</span><span class="p">()</span>
<span class="n">times</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="n">start</span>
<span class="k">return</span> <span class="n">times</span>
<span class="k">def</span> <span class="nf">bench</span><span class="p">(</span><span class="n">funcs</span><span class="p">,</span> <span class="n">n_groups</span><span class="p">,</span> <span class="n">sizes</span><span class="p">,</span> <span class="n">n_iter</span><span class="o">=</span><span class="mi">500</span><span class="p">):</span>
<span class="s">"""Run a set of benchmarks and return as a dataframe"""</span>
<span class="n">n_groups</span><span class="p">,</span> <span class="n">sizes</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">broadcast_arrays</span><span class="p">(</span><span class="n">n_groups</span><span class="p">,</span> <span class="n">sizes</span><span class="p">)</span>
<span class="n">names</span> <span class="o">=</span> <span class="p">[</span><span class="n">func</span><span class="p">.</span><span class="n">__name__</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">'_'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">func</span> <span class="ow">in</span> <span class="n">funcs</span><span class="p">]</span>
<span class="n">dfs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">func</span> <span class="ow">in</span> <span class="n">funcs</span><span class="p">:</span>
<span class="k">for</span> <span class="n">n_group</span><span class="p">,</span> <span class="n">size</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">n_groups</span><span class="p">,</span> <span class="n">sizes</span><span class="p">):</span>
<span class="n">timings</span> <span class="o">=</span> <span class="n">time_groupby</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">n_group</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">n_iter</span><span class="o">=</span><span class="n">n_iter</span><span class="p">)</span>
<span class="n">dfs</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span><span class="p">({</span>
<span class="s">'Times (s)'</span><span class="p">:</span> <span class="n">timings</span><span class="p">,</span>
<span class="s">'Name'</span><span class="p">:</span> <span class="p">[</span><span class="n">func</span><span class="p">.</span><span class="n">__name__</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">'_'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]]</span><span class="o">*</span><span class="n">n_iter</span><span class="p">,</span>
<span class="s">'Num Groups'</span><span class="p">:</span> <span class="p">[</span><span class="n">n_group</span><span class="p">]</span><span class="o">*</span><span class="n">n_iter</span><span class="p">,</span>
<span class="s">'Size'</span><span class="p">:</span> <span class="p">[</span><span class="n">size</span><span class="p">]</span><span class="o">*</span><span class="n">n_iter</span><span class="p">,</span>
<span class="p">}))</span>
<span class="k">return</span> <span class="n">pd</span><span class="p">.</span><span class="n">concat</span><span class="p">(</span><span class="n">dfs</span><span class="p">)</span>
<span class="n">n_groups</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10</span> <span class="o">**</span> <span class="n">np</span><span class="p">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">10</span><span class="p">)).</span><span class="n">astype</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
<span class="n">sizes</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10</span> <span class="o">**</span> <span class="n">np</span><span class="p">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">10</span><span class="p">)).</span><span class="n">astype</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
<span class="n">funcs</span> <span class="o">=</span> <span class="p">[</span><span class="n">pandas_groupby</span><span class="p">,</span> <span class="n">dict_groupby</span><span class="p">,</span> <span class="n">itertools_groupby</span><span class="p">,</span>
<span class="n">masking_groupby</span><span class="p">,</span> <span class="n">bincount_groupby</span><span class="p">,</span> <span class="n">sparse_groupby</span><span class="p">,</span>
<span class="n">list_groupby</span><span class="p">,</span> <span class="n">arange_groupby</span><span class="p">,</span> <span class="n">eye_groupby</span><span class="p">,</span> <span class="n">ndimage_groupby</span><span class="p">]</span>
<span class="n">timings_sizes</span> <span class="o">=</span> <span class="n">bench</span><span class="p">(</span><span class="n">funcs</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="n">sizes</span><span class="p">,</span> <span class="n">n_iter</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
<span class="n">timings_groups</span> <span class="o">=</span> <span class="n">bench</span><span class="p">(</span><span class="n">funcs</span><span class="p">,</span> <span class="n">n_groups</span><span class="p">,</span> <span class="mi">10000</span><span class="p">,</span> <span class="n">n_iter</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
</code></pre></div></div>
<h2 id="updates">Updates</h2>
<p>2021-02-21: Removed <code class="language-plaintext highlighter-rouge">ndimage</code> from timings, added <code class="language-plaintext highlighter-rouge">at_groupby</code>.</p>Nicholas Vadivelunicholas.vadivelu@gmail.comThe group-by (or split-apply-combine) pattern, illustrated below, is ubiquitous in data analysis. Essentially, you have data with predefined groups and want to compute some summarizing statistics for each of those groups. For example, suppose you have a set of High School students and want to estimate the average height by grade. You would need to split the dataset by grade, apply the mean operation to each group, then combine the means of all the groups together. The figure below is from the Python Data Science Handbook.Interactive Data Visualization with Altair2021-01-18T00:00:00+00:002021-01-18T00:00:00+00:00https://nicholasvadivelu.com/2021/01/18/interactive-altair<p>Through this post, we’ll explore data using <code class="language-plaintext highlighter-rouge">altair</code>, create simple
dashboards, and deploy them for others to use. This was heavily inspired by
<a href="https://www.youtube.com/watch?v=ms29ZPUKxbU">Jake VanderPlas’s workshop at PyCon
2018</a>. If this post piques
your interest, definitely check that video out for a longer more in depth
version.</p>
<p>This article provides a summary of the live workshop, which you can watch
<a href="">here</a>.
<a href="https://colab.research.google.com/drive/1QeIfJWjMVjxvfllBDPxefH5wYNYCmn8J?usp=sharing">Here</a>
is a colab link to run all the code.</p>
<p>We’ll start by importing the libraries we need for now: <code class="language-plaintext highlighter-rouge">altair</code> and <code class="language-plaintext highlighter-rouge">pandas</code>.
<code class="language-plaintext highlighter-rouge">pandas</code> is a data analysis library in python which provides a <code class="language-plaintext highlighter-rouge">DataFrame</code> to
represent tabular data. Don’t worry if you aren’t familiar with it–we’ll cover
what you need as we go.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">altair</span> <span class="k">as</span> <span class="n">alt</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>
</code></pre></div></div>
<p>We’ll use a Pokemon dataset to demonstrate the library. This dataset contains
data about Pokemon stats, moves, and competitive tiers from Gen VI. Don’t worry
if you don’t understand Pokemon for this workshop!</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">csv_url</span> <span class="o">=</span> <span class="s">'https://raw.githubusercontent.com/n2cholas/dsc-workshops/master/Intro_to_Interactive_Data_Viz_with_Altair/pokemon-data-cleaned.csv'</span>
<span class="c1"># Turn off na_filter so blanks aren't read as NA
</span><span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="n">csv_url</span><span class="p">,</span> <span class="n">na_filter</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</code></pre></div></div>
<h2 id="preliminaries">Preliminaries</h2>
<p>This post was created in an environment called Google Colab, which is a Jupyter
notebook hosted by Google. It runs in your browser, and you optionally have
access to hardware accelerators like GPUs or TPUs.</p>
<p>A Jupyter Notebook is a web-based application that allows you to create
documents of live code, visualizations, equations, and markdown text. Its
interactive nature makes it great for data analysis. Before moving on, here are
some useful tricks:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">?</span><span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span> <span class="c1"># gives you the function/class signature with the description
</span><span class="err">??</span><span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span> <span class="c1"># two question marks gives you the actual code for that function
</span></code></pre></div></div>
<p>Commands prefaced by “%” or “%%” are called magic commands. You can read about
more <a href="https://ipython.readthedocs.io/en/stable/interactive/magics.html">here</a>.</p>
<h2 id="preprocessing">Preprocessing</h2>
<p>We’ll start by processing the data a bit to make it easier to work with. Don’t
worry about these steps for this workshop. If you’re curious, check out <a href="https://nicholasvadivelu.com/2019/09/27/intro-to-pandas/">this
blog post</a> on using
<code class="language-plaintext highlighter-rouge">pandas</code> to clean up this dataset.</p>
<p>On a high level, we are consolidating one of the categorical features so that
it is easier to visualize.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Narrow scope of data
</span><span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'OUBL'</span><span class="p">,</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'Uber'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'UUBL'</span><span class="p">,</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'OU'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'RUBL'</span><span class="p">,</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'UU'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'NUBL'</span><span class="p">,</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'RU'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'PUBL'</span><span class="p">,</span><span class="s">'Tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'NU'</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">].</span><span class="n">isin</span><span class="p">([</span><span class="s">'Uber'</span><span class="p">,</span> <span class="s">'OU'</span><span class="p">,</span> <span class="s">'UU'</span><span class="p">,</span> <span class="s">'NU'</span><span class="p">,</span> <span class="s">'RU'</span><span class="p">,</span> <span class="s">'PU'</span><span class="p">])]</span>
</code></pre></div></div>
<h2 id="visualization">Visualization</h2>
<p>Before visualizing data, make sure your data is in a standard format:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">sample</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Name</th>
<th>Tier</th>
<th>Num Types</th>
<th>Type 1</th>
<th>Type 2</th>
<th>Num Abilities</th>
<th>Ability 1</th>
<th>Ability 2</th>
<th>Ability 3</th>
<th>Has Negative Ability</th>
<th>HP</th>
<th>Attack</th>
<th>Defense</th>
<th>Special Attack</th>
<th>Special Defense</th>
<th>Speed</th>
<th>Base Stat Total</th>
<th>Next Evolution(s)</th>
<th>Evolutionary Stage</th>
<th>Num Evolutionary Stages</th>
<th>Evolutionary Progress</th>
<th>Is Mega Evolution</th>
<th>Is Alternate Form</th>
<th>Num Moves</th>
<th>Moves</th>
<th>Defensive Boost Moves</th>
<th>Offensive Boost Moves</th>
<th>Max Defensive Boost Amount</th>
<th>Max Offensive Boost Amount</th>
<th>Recovery Moves</th>
<th>Priority STAB Attacks</th>
<th>Entry Hazards</th>
<th>Hazard Clearing Moves</th>
<th>Phazing Moves</th>
<th>Switch Attacks</th>
<th>High Prob Side FX Attacks</th>
<th>Constant Damage Attacks</th>
<th>Trapping Moves</th>
</tr>
</thead>
<tbody>
<tr>
<th>84</th>
<td>Bruxish</td>
<td>RU</td>
<td>2</td>
<td>Psychic</td>
<td>Water</td>
<td>3</td>
<td>Dazzling</td>
<td>Strong Jaw</td>
<td>Wonder Skin</td>
<td>0</td>
<td>68</td>
<td>105</td>
<td>70</td>
<td>70</td>
<td>70</td>
<td>92</td>
<td>475</td>
<td>[]</td>
<td>1</td>
<td>1</td>
<td>1.0</td>
<td>0</td>
<td>0</td>
<td>54</td>
<td>{'Toxic', 'Light Screen', 'Blizzard', 'Screech...</td>
<td>{'Bulk Up', 'Calm Mind'}</td>
<td>{'Bulk Up', 'Swords Dance', 'Calm Mind'}</td>
<td>1</td>
<td>2</td>
<td>set()</td>
<td>{'Aqua Jet'}</td>
<td>set()</td>
<td>set()</td>
<td>set()</td>
<td>set()</td>
<td>set()</td>
<td>set()</td>
<td>set()</td>
</tr>
</tbody>
</table>
</div>
<p>Each row should be an observation (here, a Pokemon) and each column should be a
feature (i.e. a property of the observation). Features can be continuous
variables, a category, etc.</p>
<p>We’ll remove some columns we don’t need for this workshop to make this webpage
more lightweight (you’ll see why this matters later):</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">drop</span><span class="p">([</span>
<span class="s">'Num Types'</span><span class="p">,</span> <span class="s">'Type 1'</span><span class="p">,</span> <span class="s">'Type 2'</span><span class="p">,</span> <span class="s">'Num Abilities'</span><span class="p">,</span> <span class="s">'Ability 1'</span><span class="p">,</span>
<span class="s">'Ability 2'</span><span class="p">,</span> <span class="s">'Ability 3'</span><span class="p">,</span> <span class="s">'Has Negative Ability'</span><span class="p">,</span> <span class="s">'HP'</span><span class="p">,</span> <span class="s">'Attack'</span><span class="p">,</span>
<span class="s">'Defense'</span><span class="p">,</span> <span class="s">'Special Attack'</span><span class="p">,</span> <span class="s">'Special Defense'</span><span class="p">,</span> <span class="s">'Speed'</span><span class="p">,</span>
<span class="s">'Next Evolution(s)'</span><span class="p">,</span> <span class="s">'Evolutionary Stage'</span><span class="p">,</span>
<span class="s">'Num Evolutionary Stages'</span><span class="p">,</span> <span class="s">'Evolutionary Progress'</span><span class="p">,</span>
<span class="s">'Is Mega Evolution'</span><span class="p">,</span> <span class="s">'Is Alternate Form'</span><span class="p">,</span> <span class="s">'Moves'</span><span class="p">,</span>
<span class="s">'Defensive Boost Moves'</span><span class="p">,</span> <span class="s">'Offensive Boost Moves'</span><span class="p">,</span>
<span class="s">'Max Defensive Boost Amount'</span><span class="p">,</span> <span class="s">'Max Offensive Boost Amount'</span><span class="p">,</span>
<span class="s">'Recovery Moves'</span><span class="p">,</span> <span class="s">'Priority STAB Attacks'</span><span class="p">,</span> <span class="s">'Entry Hazards'</span><span class="p">,</span>
<span class="s">'Hazard Clearing Moves'</span><span class="p">,</span> <span class="s">'Phazing Moves'</span><span class="p">,</span> <span class="s">'Switch Attacks'</span><span class="p">,</span>
<span class="s">'High Prob Side FX Attacks'</span><span class="p">,</span> <span class="s">'Constant Damage Attacks'</span><span class="p">,</span>
<span class="s">'Trapping Moves'</span><span class="p">],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">sample</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Name</th>
<th>Tier</th>
<th>Base Stat Total</th>
<th>Num Moves</th>
</tr>
</thead>
<tbody>
<tr>
<th>193</th>
<td>Drampa</td>
<td>PU</td>
<td>485</td>
<td>65</td>
</tr>
</tbody>
</table>
</div>
<p>Through this post, we’ll be working towards creating a plot like this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">multi</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_multi</span><span class="p">(</span><span class="n">fields</span><span class="o">=</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">],</span> <span class="n">empty</span><span class="o">=</span><span class="s">'all'</span><span class="p">)</span>
<span class="n">interval</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_interval</span><span class="p">(</span><span class="n">encodings</span><span class="o">=</span><span class="p">[</span><span class="s">'y'</span><span class="p">])</span>
<span class="n">scatter</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span>
<span class="n">multi</span> <span class="o">&</span> <span class="n">interval</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">interval</span>
<span class="p">)</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'average(Base Stat Total)'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">multi</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">multi</span>
<span class="p">).</span><span class="n">transform_filter</span><span class="p">(</span>
<span class="n">interval</span>
<span class="p">)</span>
<span class="n">plot</span> <span class="o">=</span> <span class="n">scatter</span> <span class="o">&</span> <span class="n">bar</span>
<span class="n">plot</span>
</code></pre></div></div>
<div id="altair-viz-a63dab3aaaea4e6e84bccc4cc1bded48"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-a63dab3aaaea4e6e84bccc4cc1bded48") {
outputDiv = document.getElementById("altair-viz-a63dab3aaaea4e6e84bccc4cc1bded48");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "vconcat": [{"mark": "point", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": {"and": ["selector001", "selector002"]}}, "value": "lightgray"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector002": {"type": "interval", "encodings": ["y"]}}}, {"mark": "bar", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector001"}, "value": "lightgray"}, "x": {"type": "quantitative", "aggregate": "average", "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "selection": {"selector001": {"type": "multi", "fields": ["Tier"], "empty": "all"}}, "transform": [{"filter": {"selection": "selector002"}}]}], "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Above, we have a scatter plot above showing the relationship between the base
state total of a Pokemon (an indicator of its strength) and the number of of
moves it can learn. Below, we have the average base stat total by the tier. We
can create a selection of the scatter plot across the y-interval, which
controls which data points are used in the bar plot to show the averages. We
can click individual bars (or shift-click multiple bars) to control which
points are highlighted in the above plot.</p>
<p>Let’s start with something simpler, which is just the scatter plot without
interaction:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">tooltip</span><span class="o">=</span><span class="s">'Name'</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">title</span><span class="o">=</span><span class="s">'Pokemon Data'</span>
<span class="p">).</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<div id="altair-viz-671e379b26bb4830891576b4e08600f6"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-671e379b26bb4830891576b4e08600f6") {
outputDiv = document.getElementById("altair-viz-671e379b26bb4830891576b4e08600f6");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"color": {"type": "nominal", "field": "Tier"}, "tooltip": {"type": "nominal", "field": "Name"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector003": {"type": "interval", "bind": "scales", "encodings": ["x", "y"]}}, "title": "Pokemon Data", "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Let’s break down how each line works.</p>
<p>Altair produces plots that follow a specification called Vega Lite, which we’ll
cover in more detail later. Essentially, it has the ability to create and
verify a schema that describes how a plot should be constructed. This schema is
used by a JavaScript front-end to render our plot.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
SchemaValidationError: Invalid specification
altair.vegalite.v4.api.Chart, validating 'required'
'mark' is a required property
</pre></div>
<p>We get a <code class="language-plaintext highlighter-rouge">SchemaValidationError</code> because we need a type of mark, which
represents our data. As mentioned, an <code class="language-plaintext highlighter-rouge">alt.Chart</code> both creates and verifies the
schema.</p>
<p>In our opening example, we saw <code class="language-plaintext highlighter-rouge">mark_point()</code>, which creates a scatter plot.
There are many others, such as <code class="language-plaintext highlighter-rouge">mark_bar()</code>, <code class="language-plaintext highlighter-rouge">mark_tick()</code>, and more. You can
read about them all <a href="https://altair-viz.github.io/user_guide/marks.html">here</a>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-d4d663a1952d4fe789d5fae759441d68"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-d4d663a1952d4fe789d5fae759441d68") {
outputDiv = document.getElementById("altair-viz-d4d663a1952d4fe789d5fae759441d68");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": {"type": "point", "size": 10}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>We made a scatter plot! There is a point for every row in the dataset, but you
can’t tell because they’re all stacked on top of eachother. We also adjusted
the size of our points by passing in <code class="language-plaintext highlighter-rouge">size=10</code> to <code class="language-plaintext highlighter-rouge">mark_point()</code>. This is not
useful yet, as it doesn’t portray any information. We need to tell Altair how
to encode these points to get a real scatterplot.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-53642fe6b58747cd957071da23b67e61"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-53642fe6b58747cd957071da23b67e61") {
outputDiv = document.getElementById("altair-viz-53642fe6b58747cd957071da23b67e61");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"x": {"type": "quantitative", "field": "Base Stat Total"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>We’re getting there, are now encoding the points in one dimension. To be
precise, we told <code class="language-plaintext highlighter-rouge">altair</code> to encode Base State Total along the x-axis.</p>
<p>It’s a bit hard to see, we can change the type of mark to see things more
clearly:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_tick</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-3806750c30cb469e9b7b94a96b2f23b0"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-3806750c30cb469e9b7b94a96b2f23b0") {
outputDiv = document.getElementById("altair-viz-3806750c30cb469e9b7b94a96b2f23b0");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "tick", "encoding": {"x": {"type": "quantitative", "field": "Base Stat Total"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>But we digress, we wanted a scatter plot. Let’s encode the Number of moves in y-axis too.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-7c531e0aa9024359afce9ec2cdcbfa5c"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-7c531e0aa9024359afce9ec2cdcbfa5c") {
outputDiv = document.getElementById("altair-viz-7c531e0aa9024359afce9ec2cdcbfa5c");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Let’s work towards making a histogram of <code class="language-plaintext highlighter-rouge">Base Stat Total</code>s, starting with the
scatter plot we already make. If you’re used to other plotting frameworks, this
may seem strange to you–scatterplots and histograms are completely different.
But Altair gives us a declarative visualization grammar to build plots. We can
use basic building blocks to make a wide variety of plots. Don’t worry if that
didn’t make sense–let’s see it in action.</p>
<p>First, let’s count the number of <code class="language-plaintext highlighter-rouge">Base Stat Total</code> that take on each value:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-7cd4c327c11b4c7bba46b3c147612002"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-7cd4c327c11b4c7bba46b3c147612002") {
outputDiv = document.getElementById("altair-viz-7cd4c327c11b4c7bba46b3c147612002");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "aggregate": "count"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>We used the string <code class="language-plaintext highlighter-rouge">count()</code> to indicatate that we want to count the number of
points. If we didn’t encode Base Stat Total in the x-axis, we would just count
the total number of points, like shown below:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">y</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-8df636c7f5fe4dbfa8d70165ad95d6ff"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-8df636c7f5fe4dbfa8d70165ad95d6ff") {
outputDiv = document.getElementById("altair-viz-8df636c7f5fe4dbfa8d70165ad95d6ff");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"y": {"type": "quantitative", "aggregate": "count"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Pretty interesting that so many pokemon have a <code class="language-plaintext highlighter-rouge">Base Stat Total</code> of 600, but
this plot is not so useful to understand other trends, since there are too many
values the base stat totals take on. Let’s bin the x-axis:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">X</span><span class="p">(</span><span class="s">'Base Stat Total'</span><span class="p">,</span> <span class="nb">bin</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">y</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-7d713d805d334ccda3fb2d24d4fc791f"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-7d713d805d334ccda3fb2d24d4fc791f") {
outputDiv = document.getElementById("altair-viz-7d713d805d334ccda3fb2d24d4fc791f");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"x": {"type": "quantitative", "bin": true, "field": "Base Stat Total"}, "y": {"type": "quantitative", "aggregate": "count"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Points are not the standard choice to understand the distribution of this
variate, let’s use a bar:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">X</span><span class="p">(</span><span class="s">'Base Stat Total'</span><span class="p">,</span> <span class="nb">bin</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">y</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-db8f074e86d649039a449c4ec3e9b076"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-db8f074e86d649039a449c4ec3e9b076") {
outputDiv = document.getElementById("altair-viz-db8f074e86d649039a449c4ec3e9b076");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "bar", "encoding": {"x": {"type": "quantitative", "bin": true, "field": "Base Stat Total"}, "y": {"type": "quantitative", "aggregate": "count"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Ta-da, a histogram! You can typically rely on Altair to pick good defaults, but
if you want more fine-tuned control, you can always tweak things. For example,
let’s increase the number of bins:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">X</span><span class="p">(</span><span class="s">'Base Stat Total'</span><span class="p">,</span> <span class="nb">bin</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">Bin</span><span class="p">(</span><span class="n">maxbins</span><span class="o">=</span><span class="mi">30</span><span class="p">)),</span>
<span class="n">y</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-e065101bbe4e4e1386b09550df586754"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-e065101bbe4e4e1386b09550df586754") {
outputDiv = document.getElementById("altair-viz-e065101bbe4e4e1386b09550df586754");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "bar", "encoding": {"color": {"type": "nominal", "field": "Tier"}, "x": {"type": "quantitative", "bin": {"maxbins": 30}, "field": "Base Stat Total"}, "y": {"type": "quantitative", "aggregate": "count"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Nice, we have a pretty handsome histogram! Using Altair’s expressive API, we
don’t need to worry about specific calls to make histograms or scatterplots: we
just need to remember the basic building plots.</p>
<p>We also added the color to show the distribution by Tier, but this is not so
clear. Let’s try to make a heatmap to illustrate this instead:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">X</span><span class="p">(</span><span class="s">'Base Stat Total'</span><span class="p">,</span> <span class="nb">bin</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">Bin</span><span class="p">(</span><span class="n">maxbins</span><span class="o">=</span><span class="mi">30</span><span class="p">)),</span>
<span class="n">color</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-785ba85f721347bc98a38c460534cf8e"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-785ba85f721347bc98a38c460534cf8e") {
outputDiv = document.getElementById("altair-viz-785ba85f721347bc98a38c460534cf8e");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "bar", "encoding": {"color": {"type": "quantitative", "aggregate": "count"}, "x": {"type": "quantitative", "bin": {"maxbins": 30}, "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Just by switching <code class="language-plaintext highlighter-rouge">y</code> and <code class="language-plaintext highlighter-rouge">color</code>, we were able to make a heatmap using the
expressive building blocks Altair provides. Notice that Altair chooses an
appropriate colour scale for this continuous variable (whereas before it was
choosing a scale for discrete categories).</p>
<p>But this still isn’t great for understanding distributions, let’s split this
into multiple histograms by tier:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">75</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">X</span><span class="p">(</span><span class="s">'Base Stat Total'</span><span class="p">,</span> <span class="nb">bin</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">Bin</span><span class="p">(</span><span class="n">maxbins</span><span class="o">=</span><span class="mi">30</span><span class="p">)),</span>
<span class="n">y</span><span class="o">=</span><span class="s">'count()'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">column</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-0000e80305c64ac0a157fb22a4fd6fb8"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-0000e80305c64ac0a157fb22a4fd6fb8") {
outputDiv = document.getElementById("altair-viz-0000e80305c64ac0a157fb22a4fd6fb8");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "bar", width: 75, "encoding": {"color": {"type": "nominal", "field": "Tier"}, "column": {"type": "nominal", "field": "Tier"}, "x": {"type": "quantitative", "bin": {"maxbins": 30}, "field": "Base Stat Total"}, "y": {"type": "quantitative", "aggregate": "count"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Great! Now we can clearly see the distributions of Base Stat Totals by tier.</p>
<p>Let’s move onto a different sort of plot. What if we’re interested in the
average BST by tier?</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'average(Base Stat Total)'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-a1632bdb726641528e1eed3b11ab00c0"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-a1632bdb726641528e1eed3b11ab00c0") {
outputDiv = document.getElementById("altair-viz-a1632bdb726641528e1eed3b11ab00c0");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "bar", "encoding": {"color": {"type": "nominal", "field": "Tier"}, "x": {"type": "quantitative", "aggregate": "average", "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p><code class="language-plaintext highlighter-rouge">'count()'</code> and <code class="language-plaintext highlighter-rouge">'average()'</code> are examples of data aggregations. Since we’re taking the average by tiers, we can think of it as a split-apply-combine, illustrated below:</p>
<p><img src="https://blog.dask.org/images/split-apply-combine.png" alt="" />.</p>
<p>We split by some key (<code class="language-plaintext highlighter-rouge">x</code> in the diagram, <code class="language-plaintext highlighter-rouge">tier</code> in our example), apply some aggregation (e.g. <code class="language-plaintext highlighter-rouge">average</code>), then combine the data back together.</p>
<p>In pandas, you would do this as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">groupby</span><span class="p">(</span><span class="s">'Tier'</span><span class="p">)[</span><span class="s">'Base Stat Total'</span><span class="p">].</span><span class="n">mean</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
NU 495.132353
OU 565.896104
PU 464.165919
RU 524.486111
UU 538.181818
Uber 657.042553
Name: Base Stat Total, dtype: float64
</pre>
</div>
<p>Before moving onto interaction, let’s briefly discuss datatypes.</p>
<table>
<thead>
<tr>
<th>Data Type</th>
<th>Shorthand Code</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>quantitative</td>
<td>Q</td>
<td>a continuous real-valued quantity</td>
</tr>
<tr>
<td>ordinal</td>
<td>O</td>
<td>a discrete ordered quantity</td>
</tr>
<tr>
<td>nominal</td>
<td>N</td>
<td>a discrete unordered category</td>
</tr>
<tr>
<td>temporal</td>
<td>T</td>
<td>a time or date value</td>
</tr>
<tr>
<td>geojson</td>
<td>G</td>
<td>a geographic shape</td>
</tr>
</tbody>
</table>
<p>These are typically inferred from your pandas DataFrame. When you don’t use a
DataFrame, however, you need to specify these. It helps Altair choose the
appropriate encoding and scales. For example, if you use a color scale for a
quantitative variable, you likely want a smooth gradient. For a nominal
variable, you likely want dicrete colours. For a an ordinal variable, you
probably want discrete colours that increase in intensity to represent the
order. You can read more about them
<a href="https://altair-viz.github.io/user_guide/encoding.html#encoding-data-types">here</a>.</p>
<p>I’d recommend always explicitly specifying them, as shown below.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">csv_url</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total:Q'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves:Q'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier:N'</span><span class="p">,</span>
<span class="n">tooltip</span><span class="o">=</span><span class="s">'Name:N'</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-f9f5cc0918834cacb3f26ce706413d40"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-f9f5cc0918834cacb3f26ce706413d40") {
outputDiv = document.getElementById("altair-viz-f9f5cc0918834cacb3f26ce706413d40");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"url": "https://raw.githubusercontent.com/n2cholas/dsc-workshops/master/Intro_to_Interactive_Data_Viz_with_Altair/pokemon-data-cleaned.csv"}, "mark": "point", "encoding": {"color": {"type": "nominal", "field": "Tier"}, "tooltip": {"type": "nominal", "field": "Name"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json"}, {"mode": "vega-lite"});
</script>
<p>Since we specified the data types, we were able to consume the CSV straight
from the web. Without the data types, we get an error:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">csv_url</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">tooltip</span><span class="o">=</span><span class="s">'Name'</span>
<span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
-----------------------------------------------------------------
ValueError Traceback (most recent call last)
...
ValueError: Tier encoding field is specified without a type; the
type cannot be automatically inferred because the data is not
specified as a pandas.DataFrame.
</pre>
</div>
<p>Since we’re using <code class="language-plaintext highlighter-rouge">pandas</code> DataFrames, we will skip out on specifying the data
type since they are inferred.</p>
<h2 id="interaction">Interaction</h2>
<p>So far, we’ve only seen basic panning and zooming within plots (by adding
<code class="language-plaintext highlighter-rouge">.interactive()</code>), but we can build far more interesting interactions. Let’s
start with an interval selection.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">interval</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_interval</span><span class="p">()</span>
<span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">interval</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-e8011258e1b54e05ac665d4660ef960b"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-e8011258e1b54e05ac665d4660ef960b") {
outputDiv = document.getElementById("altair-viz-e8011258e1b54e05ac665d4660ef960b");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"color": {"type": "nominal", "field": "Tier"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector004": {"type": "interval"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Now we can make selection rectangles in our plot. Let’s make it highlight the
selected points:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">interval</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_interval</span><span class="p">()</span>
<span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">interval</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">interval</span>
<span class="p">)</span>
</code></pre></div></div>
<div id="altair-viz-dc8aa4f01dfc4e1285f0e5c9a9dedd4b"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-dc8aa4f01dfc4e1285f0e5c9a9dedd4b") {
outputDiv = document.getElementById("altair-viz-dc8aa4f01dfc4e1285f0e5c9a9dedd4b");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "mark": "point", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector005"}, "value": "lightgray"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector005": {"type": "interval"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>For all the types of selections, you can use <code class="language-plaintext highlighter-rouge">alt.condition</code> to control various
aspects of the plot. The first argument is the predicate (here, the selection
object), the second argument is the value the encoded data assumes when the
condition is true (i.e. when selected), the third is the value they assume when
not selected.</p>
<p>When you make a selection, this gives the JavaScript a signal about what points
are inside vs. outside the selection, which drives actions such as
<code class="language-plaintext highlighter-rouge">alt.condition</code>.</p>
<p>Since the selections act on the data points themselves, so we can tie together
data on multiple plots:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">interval</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_interval</span><span class="p">(</span><span class="n">encodings</span><span class="o">=</span><span class="p">[</span><span class="s">'y'</span><span class="p">])</span>
<span class="n">scatter</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">interval</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">interval</span>
<span class="p">)</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'average(Base Stat Total)'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s">'Tier'</span>
<span class="p">).</span><span class="n">transform_filter</span><span class="p">(</span>
<span class="n">interval</span>
<span class="p">)</span>
<span class="n">scatter</span> <span class="o">&</span> <span class="n">bar</span> <span class="c1"># vertically concatenates plots
# scatter | bar # horizontally concatenates plots
</span></code></pre></div></div>
<div id="altair-viz-fc62d4d3fbbc41e4a01295931f74156c"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-fc62d4d3fbbc41e4a01295931f74156c") {
outputDiv = document.getElementById("altair-viz-fc62d4d3fbbc41e4a01295931f74156c");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "vconcat": [{"mark": "point", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector006"}, "value": "lightgray"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector006": {"type": "interval", "encodings": ["y"]}}}, {"mark": "bar", "encoding": {"color": {"type": "nominal", "field": "Tier"}, "x": {"type": "quantitative", "aggregate": "average", "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "transform": [{"filter": {"selection": "selector006"}}]}], "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>We did a bunch of things there, let’s break it down. First, we constrained our
<code class="language-plaintext highlighter-rouge">selection_interval</code> to only operate on the y encoding, so we can’t make
freeform boxes. Next, we created a bar chart like above, with a
<code class="language-plaintext highlighter-rouge">transform_filter</code> to only consider points selected by the interval. To be
clear, the <code class="language-plaintext highlighter-rouge">transform_filter</code> takes in a predicate, which in this case is
whether or not a point is in the selection (represented by the selection
object). Finally, we used <code class="language-plaintext highlighter-rouge">scatter & bar</code> to vertically concatenate both plots
(we could also use <code class="language-plaintext highlighter-rouge">alt.voncat(scatter, bar)</code>.</p>
<p>The result is a plot where we can look at the average base stat total by tier
where we can filter what data we consider by the number of moves the Pokemon
learn.</p>
<p>Let’s try using a multiselect to control what’s shown on the scatterplot with
the barplot.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">multi</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_multi</span><span class="p">(</span><span class="n">fields</span><span class="o">=</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">])</span>
<span class="n">scatter</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">multi</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'average(Base Stat Total)'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">multi</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">multi</span>
<span class="p">)</span>
<span class="n">scatter</span> <span class="o">&</span> <span class="n">bar</span>
</code></pre></div></div>
<div id="altair-viz-2518e092bb684df883cad217458f6702"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-2518e092bb684df883cad217458f6702") {
outputDiv = document.getElementById("altair-viz-2518e092bb684df883cad217458f6702");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "vconcat": [{"mark": "point", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector007"}, "value": "lightgray"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}}, {"mark": "bar", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector007"}, "value": "lightgray"}, "x": {"type": "quantitative", "aggregate": "average", "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "selection": {"selector007": {"type": "multi", "fields": ["Tier"]}}}], "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Now, our selection is on the Tier in the bar plot, and we’re altering the
colour of the scatter plot depending on what’s selected. Only the pokemon
belonging tot he bars that are selected will be highlighted in our plot. If you
hold shift, you can select multiple bars.</p>
<p>Let’s add two-way interaction and finalize our plot:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">multi</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_multi</span><span class="p">(</span><span class="n">fields</span><span class="o">=</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">],</span> <span class="n">empty</span><span class="o">=</span><span class="s">'all'</span><span class="p">)</span>
<span class="n">interval</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_interval</span><span class="p">(</span><span class="n">encodings</span><span class="o">=</span><span class="p">[</span><span class="s">'y'</span><span class="p">])</span>
<span class="n">scatter</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">multi</span> <span class="o">&</span> <span class="n">interval</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">interval</span>
<span class="p">)</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">df</span><span class="p">).</span><span class="n">mark_bar</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'average(Base Stat Total)'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Tier'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">multi</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">multi</span>
<span class="p">).</span><span class="n">transform_filter</span><span class="p">(</span>
<span class="n">interval</span>
<span class="p">)</span>
<span class="n">plot</span> <span class="o">=</span> <span class="n">scatter</span> <span class="o">&</span> <span class="n">bar</span>
<span class="n">plot</span>
</code></pre></div></div>
<div id="altair-viz-1cba280cf37d4b56895223a683df426f"></div>
<script type="text/javascript">
(function(spec, embedOpt){
let outputDiv = document.currentScript.previousElementSibling;
if (outputDiv.id !== "altair-viz-1cba280cf37d4b56895223a683df426f") {
outputDiv = document.getElementById("altair-viz-1cba280cf37d4b56895223a683df426f");
}
const paths = {
"vega": "https://cdn.jsdelivr.net/npm//vega@5?noext",
"vega-lib": "https://cdn.jsdelivr.net/npm//vega-lib?noext",
"vega-lite": "https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext",
"vega-embed": "https://cdn.jsdelivr.net/npm//vega-embed@6?noext",
};
function loadScript(lib) {
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.src = paths[lib];
s.async = true;
s.onload = () => resolve(paths[lib]);
s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
document.getElementsByTagName("head")[0].appendChild(s);
});
}
function showError(err) {
outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
throw err;
}
function displayChart(vegaEmbed) {
vegaEmbed(outputDiv, spec, embedOpt)
.catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
}
if(typeof define === "function" && define.amd) {
requirejs.config({paths});
require(["vega-embed"], displayChart, err => showError(`Error loading script: ${err.message}`));
} else if (typeof vegaEmbed === "function") {
displayChart(vegaEmbed);
} else {
loadScript("vega")
.then(() => loadScript("vega-lite"))
.then(() => loadScript("vega-embed"))
.catch(showError)
.then(() => displayChart(vegaEmbed));
}
})({"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "vconcat": [{"mark": "point", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": {"and": ["selector008", "selector009"]}}, "value": "lightgray"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector009": {"type": "interval", "encodings": ["y"]}}}, {"mark": "bar", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector008"}, "value": "lightgray"}, "x": {"type": "quantitative", "aggregate": "average", "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "selection": {"selector008": {"type": "multi", "fields": ["Tier"], "empty": "all"}}, "transform": [{"filter": {"selection": "selector009"}}]}], "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}}, {"mode": "vega-lite"});
</script>
<p>Now, we combined the multi-selection and the interval selection in our plots.</p>
<p>We only look a look at one case of using interactions. Read more about the
types of selections, selection defaults, how to trigger those selections, and
what you can do with those selections
<a href="https://altair-viz.github.io/user_guide/interactions.html#selection-types-interval-single-multi">here</a>.</p>
<h2 id="deploying-your-visualization">Deploying Your Visualization</h2>
<p>Altair creates a Vega Lite specification. Let’s take a small subset of our data
to understand exactly what that is:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">small_df</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">sample</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">small_df</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Name</th>
<th>Tier</th>
<th>Base Stat Total</th>
<th>Num Moves</th>
</tr>
</thead>
<tbody>
<tr>
<th>600</th>
<td>Plusle</td>
<td>PU</td>
<td>405</td>
<td>76</td>
</tr>
<tr>
<th>71</th>
<td>Blaziken-Mega</td>
<td>Uber</td>
<td>630</td>
<td>107</td>
</tr>
</tbody>
</table>
</div>
<p>We take a random sample of two points in our dataset.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">multi</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_multi</span><span class="p">(</span><span class="n">fields</span><span class="o">=</span><span class="p">[</span><span class="s">'Tier'</span><span class="p">],</span> <span class="n">empty</span><span class="o">=</span><span class="s">'all'</span><span class="p">)</span>
<span class="n">interval</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">selection_interval</span><span class="p">(</span><span class="n">encodings</span><span class="o">=</span><span class="p">[</span><span class="s">'y'</span><span class="p">])</span>
<span class="n">scatter</span> <span class="o">=</span> <span class="n">alt</span><span class="p">.</span><span class="n">Chart</span><span class="p">(</span><span class="n">small_df</span><span class="p">).</span><span class="n">mark_point</span><span class="p">().</span><span class="n">encode</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="s">'Base Stat Total'</span><span class="p">,</span>
<span class="n">y</span><span class="o">=</span><span class="s">'Num Moves'</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="n">alt</span><span class="p">.</span><span class="n">condition</span><span class="p">(</span><span class="n">multi</span> <span class="o">&</span> <span class="n">interval</span><span class="p">,</span> <span class="s">'Tier'</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="s">'lightgray'</span><span class="p">))</span>
<span class="p">).</span><span class="n">properties</span><span class="p">(</span>
<span class="n">selection</span><span class="o">=</span><span class="n">interval</span>
<span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">scatter</span><span class="p">.</span><span class="n">to_json</span><span class="p">())</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json",
"config": {
"view": {
"continuousHeight": 300,
"continuousWidth": 400
}
},
"data": {
"name": "data-5ff54935db2d127b1e7ec247ebc34012"
},
"datasets": {
"data-5ff54935db2d127b1e7ec247ebc34012": [
{
"Base Stat Total": 405,
"Name": "Plusle",
"Num Moves": 76,
"Tier": "PU"
},
{
"Base Stat Total": 630,
"Name": "Blaziken-Mega",
"Num Moves": 107,
"Tier": "Uber"
}
]
},
"encoding": {
"color": {
"condition": {
"field": "Tier",
"selection": {
"and": [
"selector010",
"selector011"
]
},
"type": "nominal"
},
"value": "lightgray"
},
"x": {
"field": "Base Stat Total",
"type": "quantitative"
},
"y": {
"field": "Num Moves",
"type": "quantitative"
}
},
"mark": "point",
"selection": {
"selector011": {
"encodings": [
"y"
],
"type": "interval"
}
}
}
</pre>
</div>
<p>Each plot has a JSON representation containing information about the plot as
well as every data point. For this reason, <code class="language-plaintext highlighter-rouge">altair</code> doesn’t work well with huge
dataasets–the package recommends using datasets with under 5000 points. There
are ways to visualize larger datasets using <code class="language-plaintext highlighter-rouge">altair</code>, described in the
<a href="https://altair-viz.github.io/user_guide/faq.html#why-does-altair-lead-to-such-extremely-large-notebooks">docs</a>.</p>
<p>The Vega Lite specification is becoming a standard on the web (e.g. you can
upload a Vega Lite JSON to Wikipedia for interactive plots!). This Vega Lite
specification is converted to a more complex Vega representation, which is then
converted to D3.js (JavaScript).</p>
<p>This makes Altair plots easy to embed in web-pages independent of python.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="n">plot</span><span class="p">.</span><span class="n">to_html</span><span class="p">())</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<!DOCTYPE html>
<html>
<head>
<style>
.error {
color: red;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm//vega@5"> </script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm//vega-lite@4.8.1"> </script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm//vega-embed@6"> </script>
</head>
<body>
<div id="vis"> </div>
<script>
(function(vegaEmbed) {
var spec = {"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "vconcat": [{"mark": "point", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": {"and": ["selector008", "selector009"]}}, "value": "lightgray"}, "x": {"type": "quantitative", "field": "Base Stat Total"}, "y": {"type": "quantitative", "field": "Num Moves"}}, "selection": {"selector009": {"type": "interval", "encodings": ["y"]}}}, {"mark": "bar", "encoding": {"color": {"condition": {"type": "nominal", "field": "Tier", "selection": "selector008"}, "value": "lightgray"}, "x": {"type": "quantitative", "aggregate": "average", "field": "Base Stat Total"}, "y": {"type": "nominal", "field": "Tier"}}, "selection": {"selector008": {"type": "multi", "fields": ["Tier"], "empty": "all"}}, "transform": [{"filter": {"selection": "selector009"}}]}], "data": {"name": "data-4ba12c371029303f29772324f5d63a54"}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json", "datasets": {"data-4ba12c371029303f29772324f5d63a54": [{"Name": "Abomasnow", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 75}, {"Name": "Abomasnow-Mega", "Tier": "RU", "Base Stat Total": 594, "Num Moves": 75}, {"Name": "Absol", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 107}, {"Name": "Absol-Mega", "Tier": "UU", "Base Stat Total": 565, "Num Moves": 107}, {"Name": "Accelgor", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 63}, {"Name": "Aegislash", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aegislash-Blade", "Tier": "Uber", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Aerodactyl", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 90}, {"Name": "Aerodactyl-Mega", "Tier": "UU", "Base Stat Total": 615, "Num Moves": 90}, {"Name": "Aggron", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 115}, {"Name": "Aggron-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 115}, {"Name": "Alakazam", "Tier": "OU", "Base Stat Total": 500, "Num Moves": 104}, {"Name": "Alakazam-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 104}, {"Name": "Alomomola", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 57}, {"Name": "Altaria", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 87}, {"Name": "Altaria-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 87}, {"Name": "Ambipom", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 93}, {"Name": "Amoonguss", "Tier": "OU", "Base Stat Total": 464, "Num Moves": 52}, {"Name": "Ampharos", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 87}, {"Name": "Ampharos-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 87}, {"Name": "Araquanid", "Tier": "RU", "Base Stat Total": 454, "Num Moves": 46}, {"Name": "Arbok", "Tier": "PU", "Base Stat Total": 448, "Num Moves": 88}, {"Name": "Arcanine", "Tier": "UU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Arceus", "Tier": "Uber", "Base Stat Total": 720, "Num Moves": 126}, {"Name": "Archeops", "Tier": "NU", "Base Stat Total": 567, "Num Moves": 75}, {"Name": "Ariados", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 77}, {"Name": "Armaldo", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Aromatisse", "Tier": "NU", "Base Stat Total": 462, "Num Moves": 64}, {"Name": "Articuno", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Audino", "Tier": "PU", "Base Stat Total": 445, "Num Moves": 97}, {"Name": "Audino-Mega", "Tier": "NU", "Base Stat Total": 545, "Num Moves": 97}, {"Name": "Aurorus", "Tier": "PU", "Base Stat Total": 521, "Num Moves": 75}, {"Name": "Azelf", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 81}, {"Name": "Azumarill", "Tier": "OU", "Base Stat Total": 420, "Num Moves": 96}, {"Name": "Banette", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 83}, {"Name": "Banette-Mega", "Tier": "RU", "Base Stat Total": 555, "Num Moves": 83}, {"Name": "Barbaracle", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 88}, {"Name": "Basculin", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Blue", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 57}, {"Name": "Basculin-Red", "Tier": "PU", "Base Stat Total": 514, "Num Moves": 64}, {"Name": "Bastiodon", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 75}, {"Name": "Beartic", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 73}, {"Name": "Beautifly", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 63}, {"Name": "Beedrill", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 78}, {"Name": "Beedrill-Mega", "Tier": "UU", "Base Stat Total": 495, "Num Moves": 78}, {"Name": "Beheeyem", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 78}, {"Name": "Bellossom", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Bewear", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 53}, {"Name": "Bibarel", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 85}, {"Name": "Bisharp", "Tier": "OU", "Base Stat Total": 490, "Num Moves": 78}, {"Name": "Blacephalon", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 43}, {"Name": "Blastoise", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 108}, {"Name": "Blastoise-Mega", "Tier": "RU", "Base Stat Total": 630, "Num Moves": 108}, {"Name": "Blaziken", "Tier": "Uber", "Base Stat Total": 530, "Num Moves": 107}, {"Name": "Blaziken-Mega", "Tier": "Uber", "Base Stat Total": 630, "Num Moves": 107}, {"Name": "Blissey", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Bouffalant", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 64}, {"Name": "Braviary", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 54}, {"Name": "Breloom", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 85}, {"Name": "Bronzong", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Bruxish", "Tier": "RU", "Base Stat Total": 475, "Num Moves": 54}, {"Name": "Butterfree", "Tier": "PU", "Base Stat Total": 395, "Num Moves": 80}, {"Name": "Buzzwole", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Cacturne", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 93}, {"Name": "Camerupt", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Camerupt-Mega", "Tier": "RU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Carbink", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 54}, {"Name": "Carnivine", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 67}, {"Name": "Carracosta", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 70}, {"Name": "Castform", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 69}, {"Name": "Celebi", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Celesteela", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 50}, {"Name": "Chandelure", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 66}, {"Name": "Chansey", "Tier": "OU", "Base Stat Total": 450, "Num Moves": 125}, {"Name": "Charizard", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 115}, {"Name": "Charizard-Mega-X", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Charizard-Mega-Y", "Tier": "OU", "Base Stat Total": 634, "Num Moves": 115}, {"Name": "Chatot", "Tier": "PU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Cherrim", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 57}, {"Name": "Chesnaught", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 95}, {"Name": "Chimecho", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 86}, {"Name": "Cinccino", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 68}, {"Name": "Clawitzer", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 57}, {"Name": "Claydol", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 81}, {"Name": "Clefable", "Tier": "OU", "Base Stat Total": 483, "Num Moves": 145}, {"Name": "Clefairy", "Tier": "PU", "Base Stat Total": 323, "Num Moves": 142}, {"Name": "Cloyster", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 75}, {"Name": "Cobalion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Cofagrigus", "Tier": "RU", "Base Stat Total": 483, "Num Moves": 73}, {"Name": "Comfey", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 54}, {"Name": "Conkeldurr", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 72}, {"Name": "Corsola", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 88}, {"Name": "Crabominable", "Tier": "PU", "Base Stat Total": 478, "Num Moves": 54}, {"Name": "Cradily", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 76}, {"Name": "Crawdaunt", "Tier": "UU", "Base Stat Total": 468, "Num Moves": 85}, {"Name": "Cresselia", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 64}, {"Name": "Crobat", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 79}, {"Name": "Crustle", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 61}, {"Name": "Cryogonal", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 51}, {"Name": "Darkrai", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 85}, {"Name": "Darmanitan", "Tier": "UU", "Base Stat Total": 480, "Num Moves": 74}, {"Name": "Darmanitan-Zen", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 74}, {"Name": "Decidueye", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 61}, {"Name": "Dedenne", "Tier": "PU", "Base Stat Total": 431, "Num Moves": 58}, {"Name": "Delcatty", "Tier": "PU", "Base Stat Total": 400, "Num Moves": 86}, {"Name": "Delibird", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 72}, {"Name": "Delphox", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 77}, {"Name": "Deoxys", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 99}, {"Name": "Deoxys-Attack", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 96}, {"Name": "Deoxys-Defense", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 98}, {"Name": "Deoxys-Speed", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 102}, {"Name": "Dewgong", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 77}, {"Name": "Dhelmise", "Tier": "RU", "Base Stat Total": 517, "Num Moves": 52}, {"Name": "Dialga", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 80}, {"Name": "Diancie", "Tier": "NU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Diancie-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 61}, {"Name": "Diggersby", "Tier": "OU", "Base Stat Total": 423, "Num Moves": 81}, {"Name": "Ditto", "Tier": "PU", "Base Stat Total": 288, "Num Moves": 1}, {"Name": "Dodrio", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 70}, {"Name": "Donphan", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 82}, {"Name": "Doublade", "Tier": "RU", "Base Stat Total": 448, "Num Moves": 47}, {"Name": "Dragalge", "Tier": "RU", "Base Stat Total": 494, "Num Moves": 58}, {"Name": "Dragonite", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 117}, {"Name": "Drampa", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 65}, {"Name": "Drapion", "Tier": "RU", "Base Stat Total": 500, "Num Moves": 87}, {"Name": "Drifblim", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 82}, {"Name": "Druddigon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 84}, {"Name": "Dugtrio", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 76}, {"Name": "Dugtrio-Alola", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 60}, {"Name": "Dunsparce", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 89}, {"Name": "Durant", "Tier": "UU", "Base Stat Total": 484, "Num Moves": 56}, {"Name": "Dusknoir", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Dustox", "Tier": "PU", "Base Stat Total": 385, "Num Moves": 63}, {"Name": "Eelektross", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Electivire", "Tier": "PU", "Base Stat Total": 540, "Num Moves": 81}, {"Name": "Electrode", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 62}, {"Name": "Emboar", "Tier": "RU", "Base Stat Total": 528, "Num Moves": 87}, {"Name": "Emolga", "Tier": "PU", "Base Stat Total": 428, "Num Moves": 59}, {"Name": "Empoleon", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 91}, {"Name": "Entei", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 65}, {"Name": "Escavalier", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 61}, {"Name": "Espeon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Excadrill", "Tier": "OU", "Base Stat Total": 508, "Num Moves": 60}, {"Name": "Exeggutor", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 84}, {"Name": "Exeggutor-Alola", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 69}, {"Name": "Exploud", "Tier": "RU", "Base Stat Total": 490, "Num Moves": 99}, {"Name": "Farfetch'd", "Tier": "PU", "Base Stat Total": 377, "Num Moves": 87}, {"Name": "Fearow", "Tier": "PU", "Base Stat Total": 442, "Num Moves": 69}, {"Name": "Feraligatr", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Ferroseed", "Tier": "PU", "Base Stat Total": 305, "Num Moves": 54}, {"Name": "Ferrothorn", "Tier": "OU", "Base Stat Total": 489, "Num Moves": 67}, {"Name": "Flareon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 86}, {"Name": "Floatzel", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 79}, {"Name": "Florges", "Tier": "RU", "Base Stat Total": 552, "Num Moves": 61}, {"Name": "Flygon", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 93}, {"Name": "Forretress", "Tier": "RU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Froslass", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 78}, {"Name": "Furfrou", "Tier": "PU", "Base Stat Total": 472, "Num Moves": 57}, {"Name": "Furret", "Tier": "PU", "Base Stat Total": 415, "Num Moves": 98}, {"Name": "Gallade", "Tier": "NU", "Base Stat Total": 518, "Num Moves": 126}, {"Name": "Gallade-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 126}, {"Name": "Galvantula", "Tier": "RU", "Base Stat Total": 472, "Num Moves": 64}, {"Name": "Garbodor", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 64}, {"Name": "Garchomp", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 81}, {"Name": "Garchomp-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 81}, {"Name": "Gardevoir", "Tier": "RU", "Base Stat Total": 518, "Num Moves": 101}, {"Name": "Gardevoir-Mega", "Tier": "OU", "Base Stat Total": 618, "Num Moves": 101}, {"Name": "Gastrodon", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 74}, {"Name": "Genesect", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 72}, {"Name": "Gengar", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 109}, {"Name": "Gengar-Mega", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 109}, {"Name": "Gigalith", "Tier": "NU", "Base Stat Total": 515, "Num Moves": 53}, {"Name": "Girafarig", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 96}, {"Name": "Giratina", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 85}, {"Name": "Giratina-Origin", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 86}, {"Name": "Glaceon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 76}, {"Name": "Glalie", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 68}, {"Name": "Glalie-Mega", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Gligar", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 90}, {"Name": "Gliscor", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 94}, {"Name": "Gogoat", "Tier": "PU", "Base Stat Total": 531, "Num Moves": 61}, {"Name": "Golbat", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 80}, {"Name": "Golduck", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 108}, {"Name": "Golem", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 97}, {"Name": "Golem-Alola", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 67}, {"Name": "Golisopod", "Tier": "RU", "Base Stat Total": 530, "Num Moves": 62}, {"Name": "Golurk", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 78}, {"Name": "Goodra", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Gorebyss", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Gothitelle", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Gourgeist", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Large", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Small", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Gourgeist-Super", "Tier": "PU", "Base Stat Total": 494, "Num Moves": 67}, {"Name": "Granbull", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 107}, {"Name": "Greninja", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Greninja-Ash", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 63}, {"Name": "Groudon", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 89}, {"Name": "Groudon-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 89}, {"Name": "Grumpig", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 92}, {"Name": "Gumshoos", "Tier": "PU", "Base Stat Total": 418, "Num Moves": 47}, {"Name": "Gurdurr", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 68}, {"Name": "Guzzlord", "Tier": "NU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Gyarados", "Tier": "OU", "Base Stat Total": 540, "Num Moves": 89}, {"Name": "Gyarados-Mega", "Tier": "OU", "Base Stat Total": 640, "Num Moves": 89}, {"Name": "Hariyama", "Tier": "NU", "Base Stat Total": 474, "Num Moves": 91}, {"Name": "Haunter", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 87}, {"Name": "Hawlucha", "Tier": "OU", "Base Stat Total": 502, "Num Moves": 81}, {"Name": "Haxorus", "Tier": "UU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Heatmor", "Tier": "PU", "Base Stat Total": 484, "Num Moves": 73}, {"Name": "Heatran", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Heliolisk", "Tier": "NU", "Base Stat Total": 481, "Num Moves": 66}, {"Name": "Heracross", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Heracross-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Hippowdon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 60}, {"Name": "Hitmonchan", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 85}, {"Name": "Hitmonlee", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 90}, {"Name": "Hitmontop", "Tier": "NU", "Base Stat Total": 455, "Num Moves": 79}, {"Name": "Ho-Oh", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 87}, {"Name": "Honchkrow", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 82}, {"Name": "Hoopa", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Hoopa-Unbound", "Tier": "OU", "Base Stat Total": 680, "Num Moves": 78}, {"Name": "Houndoom", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 83}, {"Name": "Houndoom-Mega", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Huntail", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 66}, {"Name": "Hydreigon", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 88}, {"Name": "Hypno", "Tier": "PU", "Base Stat Total": 483, "Num Moves": 102}, {"Name": "Illumise", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 83}, {"Name": "Incineroar", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 68}, {"Name": "Infernape", "Tier": "UU", "Base Stat Total": 534, "Num Moves": 102}, {"Name": "Jellicent", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 65}, {"Name": "Jirachi", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 86}, {"Name": "Jolteon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Jumpluff", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 70}, {"Name": "Jynx", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Kabutops", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 98}, {"Name": "Kangaskhan", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 114}, {"Name": "Kangaskhan-Mega", "Tier": "Uber", "Base Stat Total": 590, "Num Moves": 114}, {"Name": "Kartana", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 35}, {"Name": "Kecleon", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 110}, {"Name": "Keldeo", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 58}, {"Name": "Kingdra", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 68}, {"Name": "Kingler", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 80}, {"Name": "Klefki", "Tier": "UU", "Base Stat Total": 470, "Num Moves": 55}, {"Name": "Klinklang", "Tier": "NU", "Base Stat Total": 520, "Num Moves": 51}, {"Name": "Komala", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 45}, {"Name": "Kommo-o", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 62}, {"Name": "Kricketune", "Tier": "PU", "Base Stat Total": 384, "Num Moves": 61}, {"Name": "Krookodile", "Tier": "UU", "Base Stat Total": 519, "Num Moves": 89}, {"Name": "Kyogre", "Tier": "Uber", "Base Stat Total": 670, "Num Moves": 67}, {"Name": "Kyogre-Primal", "Tier": "Uber", "Base Stat Total": 770, "Num Moves": 67}, {"Name": "Kyurem", "Tier": "UU", "Base Stat Total": 660, "Num Moves": 64}, {"Name": "Kyurem-Black", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Kyurem-White", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 64}, {"Name": "Landorus", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Landorus-Therian", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 60}, {"Name": "Lanturn", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 76}, {"Name": "Lapras", "Tier": "PU", "Base Stat Total": 535, "Num Moves": 93}, {"Name": "Latias", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 97}, {"Name": "Latias-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 97}, {"Name": "Latios", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 92}, {"Name": "Latios-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 92}, {"Name": "Leafeon", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 81}, {"Name": "Leavanny", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Ledian", "Tier": "PU", "Base Stat Total": 390, "Num Moves": 78}, {"Name": "Lickilicky", "Tier": "PU", "Base Stat Total": 515, "Num Moves": 97}, {"Name": "Liepard", "Tier": "PU", "Base Stat Total": 446, "Num Moves": 71}, {"Name": "Lilligant", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 61}, {"Name": "Linoone", "Tier": "RU", "Base Stat Total": 420, "Num Moves": 89}, {"Name": "Lopunny", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 95}, {"Name": "Lopunny-Mega", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 95}, {"Name": "Lucario", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 103}, {"Name": "Lucario-Mega", "Tier": "Uber", "Base Stat Total": 625, "Num Moves": 103}, {"Name": "Ludicolo", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 91}, {"Name": "Lugia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 101}, {"Name": "Lumineon", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 63}, {"Name": "Lunala", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 59}, {"Name": "Lunatone", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Lurantis", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 49}, {"Name": "Luvdisc", "Tier": "PU", "Base Stat Total": 330, "Num Moves": 57}, {"Name": "Luxray", "Tier": "PU", "Base Stat Total": 523, "Num Moves": 64}, {"Name": "Lycanroc", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 44}, {"Name": "Lycanroc-Dusk", "Tier": "RU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Lycanroc-Midnight", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 43}, {"Name": "Machamp", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 98}, {"Name": "Magcargo", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Magearna", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 52}, {"Name": "Magmortar", "Tier": "NU", "Base Stat Total": 540, "Num Moves": 80}, {"Name": "Magneton", "Tier": "UU", "Base Stat Total": 465, "Num Moves": 66}, {"Name": "Magnezone", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 63}, {"Name": "Malamar", "Tier": "NU", "Base Stat Total": 482, "Num Moves": 70}, {"Name": "Mamoswine", "Tier": "OU", "Base Stat Total": 530, "Num Moves": 76}, {"Name": "Manaphy", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 65}, {"Name": "Mandibuzz", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 64}, {"Name": "Manectric", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 66}, {"Name": "Manectric-Mega", "Tier": "UU", "Base Stat Total": 575, "Num Moves": 66}, {"Name": "Mantine", "Tier": "UU", "Base Stat Total": 485, "Num Moves": 80}, {"Name": "Maractus", "Tier": "PU", "Base Stat Total": 461, "Num Moves": 57}, {"Name": "Marowak", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 99}, {"Name": "Marowak-Alola", "Tier": "UU", "Base Stat Total": 425, "Num Moves": 74}, {"Name": "Marshadow", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 56}, {"Name": "Masquerain", "Tier": "PU", "Base Stat Total": 454, "Num Moves": 80}, {"Name": "Mawile", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 101}, {"Name": "Mawile-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 101}, {"Name": "Medicham", "Tier": "NU", "Base Stat Total": 410, "Num Moves": 96}, {"Name": "Medicham-Mega", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 96}, {"Name": "Meganium", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 79}, {"Name": "Meloetta", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meloetta-Pirouette", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 89}, {"Name": "Meowstic-F", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 73}, {"Name": "Meowstic-M", "Tier": "PU", "Base Stat Total": 466, "Num Moves": 74}, {"Name": "Mesprit", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Metagross", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Metagross-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 80}, {"Name": "Mew", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 246}, {"Name": "Mewtwo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 136}, {"Name": "Mewtwo-Mega-X", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mewtwo-Mega-Y", "Tier": "Uber", "Base Stat Total": 780, "Num Moves": 136}, {"Name": "Mienshao", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 73}, {"Name": "Mightyena", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 71}, {"Name": "Milotic", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 72}, {"Name": "Miltank", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 92}, {"Name": "Mimikyu", "Tier": "OU", "Base Stat Total": 476, "Num Moves": 59}, {"Name": "Minior", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 50}, {"Name": "Minior-Meteor", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 50}, {"Name": "Minun", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 77}, {"Name": "Mismagius", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 86}, {"Name": "Moltres", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 68}, {"Name": "Mothim", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 63}, {"Name": "Mr. Mime", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 123}, {"Name": "Mudsdale", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 41}, {"Name": "Muk", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 101}, {"Name": "Muk-Alola", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 76}, {"Name": "Musharna", "Tier": "PU", "Base Stat Total": 487, "Num Moves": 71}, {"Name": "Naganadel", "Tier": "Uber", "Base Stat Total": 540, "Num Moves": 48}, {"Name": "Necrozma", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dawn Wings-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 61}, {"Name": "Necrozma-Dusk Mane-Ultra", "Tier": "Uber", "Base Stat Total": 754, "Num Moves": 61}, {"Name": "Nidoking", "Tier": "UU", "Base Stat Total": 505, "Num Moves": 129}, {"Name": "Nidoqueen", "Tier": "RU", "Base Stat Total": 505, "Num Moves": 128}, {"Name": "Nihilego", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Ninetales", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 92}, {"Name": "Ninetales-Alola", "Tier": "OU", "Base Stat Total": 505, "Num Moves": 69}, {"Name": "Ninjask", "Tier": "PU", "Base Stat Total": 456, "Num Moves": 69}, {"Name": "Noctowl", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Noivern", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 72}, {"Name": "Octillery", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 80}, {"Name": "Omastar", "Tier": "NU", "Base Stat Total": 495, "Num Moves": 85}, {"Name": "Oranguru", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 55}, {"Name": "Oricorio", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 45}, {"Name": "Oricorio-Pa'u", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Pom-Pom", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Oricorio-Sensu", "Tier": "PU", "Base Stat Total": 476, "Num Moves": 43}, {"Name": "Pachirisu", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 70}, {"Name": "Palkia", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 83}, {"Name": "Palossand", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 48}, {"Name": "Pangoro", "Tier": "RU", "Base Stat Total": 495, "Num Moves": 100}, {"Name": "Parasect", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 85}, {"Name": "Passimian", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 58}, {"Name": "Pelipper", "Tier": "OU", "Base Stat Total": 440, "Num Moves": 76}, {"Name": "Persian", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 101}, {"Name": "Persian-Alola", "Tier": "PU", "Base Stat Total": 440, "Num Moves": 68}, {"Name": "Pheromosa", "Tier": "Uber", "Base Stat Total": 570, "Num Moves": 47}, {"Name": "Phione", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Pidgeot", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 65}, {"Name": "Pidgeot-Mega", "Tier": "UU", "Base Stat Total": 579, "Num Moves": 65}, {"Name": "Piloswine", "Tier": "NU", "Base Stat Total": 450, "Num Moves": 73}, {"Name": "Pinsir", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Pinsir-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Plusle", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 76}, {"Name": "Politoed", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 84}, {"Name": "Poliwrath", "Tier": "PU", "Base Stat Total": 510, "Num Moves": 97}, {"Name": "Porygon-Z", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 69}, {"Name": "Porygon2", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 69}, {"Name": "Primarina", "Tier": "UU", "Base Stat Total": 530, "Num Moves": 57}, {"Name": "Primeape", "Tier": "PU", "Base Stat Total": 455, "Num Moves": 114}, {"Name": "Probopass", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 74}, {"Name": "Purugly", "Tier": "PU", "Base Stat Total": 452, "Num Moves": 79}, {"Name": "Pyroar", "Tier": "PU", "Base Stat Total": 507, "Num Moves": 60}, {"Name": "Pyukumuku", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 36}, {"Name": "Quagsire", "Tier": "RU", "Base Stat Total": 430, "Num Moves": 91}, {"Name": "Qwilfish", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 78}, {"Name": "Raichu", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 107}, {"Name": "Raichu-Alola", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Raikou", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 66}, {"Name": "Rampardos", "Tier": "PU", "Base Stat Total": 495, "Num Moves": 91}, {"Name": "Rapidash", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 71}, {"Name": "Raticate", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 93}, {"Name": "Raticate-Alola", "Tier": "PU", "Base Stat Total": 413, "Num Moves": 67}, {"Name": "Rayquaza", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 92}, {"Name": "Regice", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Regigigas", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 69}, {"Name": "Regirock", "Tier": "PU", "Base Stat Total": 580, "Num Moves": 76}, {"Name": "Registeel", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 77}, {"Name": "Relicanth", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 71}, {"Name": "Reshiram", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 67}, {"Name": "Reuniclus", "Tier": "UU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Rhydon", "Tier": "NU", "Base Stat Total": 485, "Num Moves": 125}, {"Name": "Rhyperior", "Tier": "RU", "Base Stat Total": 535, "Num Moves": 110}, {"Name": "Ribombee", "Tier": "RU", "Base Stat Total": 464, "Num Moves": 51}, {"Name": "Roserade", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 73}, {"Name": "Rotom", "Tier": "NU", "Base Stat Total": 440, "Num Moves": 54}, {"Name": "Rotom-Fan", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Frost", "Tier": "PU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Heat", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Mow", "Tier": "RU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Rotom-Wash", "Tier": "OU", "Base Stat Total": 520, "Num Moves": 55}, {"Name": "Sableye", "Tier": "PU", "Base Stat Total": 380, "Num Moves": 108}, {"Name": "Sableye-Mega", "Tier": "OU", "Base Stat Total": 480, "Num Moves": 108}, {"Name": "Salamence", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 83}, {"Name": "Salamence-Mega", "Tier": "Uber", "Base Stat Total": 700, "Num Moves": 83}, {"Name": "Salazzle", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 53}, {"Name": "Samurott", "Tier": "NU", "Base Stat Total": 528, "Num Moves": 75}, {"Name": "Sandslash", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 97}, {"Name": "Sandslash-Alola", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 71}, {"Name": "Sawk", "Tier": "NU", "Base Stat Total": 465, "Num Moves": 61}, {"Name": "Sawsbuck", "Tier": "PU", "Base Stat Total": 475, "Num Moves": 63}, {"Name": "Sceptile", "Tier": "NU", "Base Stat Total": 530, "Num Moves": 104}, {"Name": "Sceptile-Mega", "Tier": "UU", "Base Stat Total": 630, "Num Moves": 104}, {"Name": "Scizor", "Tier": "UU", "Base Stat Total": 500, "Num Moves": 80}, {"Name": "Scizor-Mega", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 80}, {"Name": "Scolipede", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Scrafty", "Tier": "NU", "Base Stat Total": 488, "Num Moves": 83}, {"Name": "Scyther", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 73}, {"Name": "Seaking", "Tier": "PU", "Base Stat Total": 450, "Num Moves": 69}, {"Name": "Seismitoad", "Tier": "UU", "Base Stat Total": 509, "Num Moves": 71}, {"Name": "Serperior", "Tier": "UU", "Base Stat Total": 528, "Num Moves": 76}, {"Name": "Seviper", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 79}, {"Name": "Sharpedo", "Tier": "UU", "Base Stat Total": 460, "Num Moves": 80}, {"Name": "Sharpedo-Mega", "Tier": "UU", "Base Stat Total": 560, "Num Moves": 80}, {"Name": "Shaymin", "Tier": "RU", "Base Stat Total": 600, "Num Moves": 54}, {"Name": "Shaymin-Sky", "Tier": "Uber", "Base Stat Total": 600, "Num Moves": 53}, {"Name": "Shedinja", "Tier": "PU", "Base Stat Total": 236, "Num Moves": 67}, {"Name": "Shiftry", "Tier": "PU", "Base Stat Total": 480, "Num Moves": 104}, {"Name": "Shiinotic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 44}, {"Name": "Shuckle", "Tier": "PU", "Base Stat Total": 505, "Num Moves": 74}, {"Name": "Sigilyph", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 72}, {"Name": "Silvally", "Tier": "PU", "Base Stat Total": 570, "Num Moves": 68}, {"Name": "Simipour", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 81}, {"Name": "Simisage", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Simisear", "Tier": "PU", "Base Stat Total": 498, "Num Moves": 79}, {"Name": "Skarmory", "Tier": "OU", "Base Stat Total": 465, "Num Moves": 78}, {"Name": "Skuntank", "Tier": "PU", "Base Stat Total": 479, "Num Moves": 78}, {"Name": "Slaking", "Tier": "PU", "Base Stat Total": 670, "Num Moves": 100}, {"Name": "Slowbro", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 119}, {"Name": "Slowbro-Mega", "Tier": "UU", "Base Stat Total": 590, "Num Moves": 119}, {"Name": "Slowking", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 111}, {"Name": "Slurpuff", "Tier": "RU", "Base Stat Total": 480, "Num Moves": 56}, {"Name": "Smeargle", "Tier": "PU", "Base Stat Total": 250, "Num Moves": 1}, {"Name": "Sneasel", "Tier": "NU", "Base Stat Total": 430, "Num Moves": 98}, {"Name": "Snorlax", "Tier": "RU", "Base Stat Total": 540, "Num Moves": 118}, {"Name": "Solgaleo", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Solrock", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 83}, {"Name": "Spinda", "Tier": "PU", "Base Stat Total": 360, "Num Moves": 99}, {"Name": "Spiritomb", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 68}, {"Name": "Stakataka", "Tier": "UU", "Base Stat Total": 570, "Num Moves": 38}, {"Name": "Stantler", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 86}, {"Name": "Staraptor", "Tier": "OU", "Base Stat Total": 485, "Num Moves": 64}, {"Name": "Starmie", "Tier": "UU", "Base Stat Total": 520, "Num Moves": 89}, {"Name": "Steelix", "Tier": "NU", "Base Stat Total": 510, "Num Moves": 86}, {"Name": "Steelix-Mega", "Tier": "RU", "Base Stat Total": 610, "Num Moves": 86}, {"Name": "Stoutland", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 66}, {"Name": "Stunfisk", "Tier": "PU", "Base Stat Total": 471, "Num Moves": 69}, {"Name": "Sudowoodo", "Tier": "PU", "Base Stat Total": 410, "Num Moves": 82}, {"Name": "Suicune", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 71}, {"Name": "Sunflora", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 62}, {"Name": "Swalot", "Tier": "PU", "Base Stat Total": 467, "Num Moves": 78}, {"Name": "Swampert", "Tier": "UU", "Base Stat Total": 535, "Num Moves": 99}, {"Name": "Swampert-Mega", "Tier": "OU", "Base Stat Total": 635, "Num Moves": 99}, {"Name": "Swanna", "Tier": "PU", "Base Stat Total": 473, "Num Moves": 53}, {"Name": "Swellow", "Tier": "RU", "Base Stat Total": 455, "Num Moves": 63}, {"Name": "Swoobat", "Tier": "PU", "Base Stat Total": 425, "Num Moves": 81}, {"Name": "Sylveon", "Tier": "UU", "Base Stat Total": 525, "Num Moves": 73}, {"Name": "Talonflame", "Tier": "UU", "Base Stat Total": 499, "Num Moves": 54}, {"Name": "Tangrowth", "Tier": "OU", "Base Stat Total": 535, "Num Moves": 82}, {"Name": "Tapu Bulu", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 60}, {"Name": "Tapu Fini", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 52}, {"Name": "Tapu Koko", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 58}, {"Name": "Tapu Lele", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 53}, {"Name": "Tauros", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 79}, {"Name": "Tentacruel", "Tier": "UU", "Base Stat Total": 515, "Num Moves": 82}, {"Name": "Terrakion", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 56}, {"Name": "Throh", "Tier": "PU", "Base Stat Total": 465, "Num Moves": 64}, {"Name": "Thundurus", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 70}, {"Name": "Thundurus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Togedemaru", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 53}, {"Name": "Togekiss", "Tier": "UU", "Base Stat Total": 545, "Num Moves": 107}, {"Name": "Togetic", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 114}, {"Name": "Torkoal", "Tier": "PU", "Base Stat Total": 470, "Num Moves": 73}, {"Name": "Tornadus", "Tier": "UU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Tornadus-Therian", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 64}, {"Name": "Torterra", "Tier": "PU", "Base Stat Total": 525, "Num Moves": 84}, {"Name": "Toucannon", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 46}, {"Name": "Toxapex", "Tier": "OU", "Base Stat Total": 495, "Num Moves": 45}, {"Name": "Toxicroak", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 96}, {"Name": "Trevenant", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 76}, {"Name": "Tropius", "Tier": "PU", "Base Stat Total": 460, "Num Moves": 78}, {"Name": "Tsareena", "Tier": "RU", "Base Stat Total": 510, "Num Moves": 53}, {"Name": "Turtonator", "Tier": "PU", "Base Stat Total": 485, "Num Moves": 58}, {"Name": "Type: Null", "Tier": "PU", "Base Stat Total": 534, "Num Moves": 46}, {"Name": "Typhlosion", "Tier": "NU", "Base Stat Total": 534, "Num Moves": 95}, {"Name": "Tyranitar", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 115}, {"Name": "Tyranitar-Mega", "Tier": "OU", "Base Stat Total": 700, "Num Moves": 115}, {"Name": "Tyrantrum", "Tier": "RU", "Base Stat Total": 521, "Num Moves": 66}, {"Name": "Umbreon", "Tier": "RU", "Base Stat Total": 525, "Num Moves": 87}, {"Name": "Unfezant", "Tier": "PU", "Base Stat Total": 488, "Num Moves": 49}, {"Name": "Unown", "Tier": "PU", "Base Stat Total": 336, "Num Moves": 1}, {"Name": "Ursaring", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 105}, {"Name": "Uxie", "Tier": "NU", "Base Stat Total": 580, "Num Moves": 78}, {"Name": "Vanilluxe", "Tier": "NU", "Base Stat Total": 535, "Num Moves": 50}, {"Name": "Vaporeon", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 91}, {"Name": "Venomoth", "Tier": "UU", "Base Stat Total": 450, "Num Moves": 81}, {"Name": "Venusaur", "Tier": "NU", "Base Stat Total": 525, "Num Moves": 88}, {"Name": "Venusaur-Mega", "Tier": "OU", "Base Stat Total": 625, "Num Moves": 88}, {"Name": "Vespiquen", "Tier": "PU", "Base Stat Total": 474, "Num Moves": 65}, {"Name": "Victini", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 79}, {"Name": "Victreebel", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 81}, {"Name": "Vikavolt", "Tier": "NU", "Base Stat Total": 500, "Num Moves": 52}, {"Name": "Vileplume", "Tier": "NU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Virizion", "Tier": "RU", "Base Stat Total": 580, "Num Moves": 59}, {"Name": "Vivillon", "Tier": "NU", "Base Stat Total": 411, "Num Moves": 59}, {"Name": "Volbeat", "Tier": "PU", "Base Stat Total": 430, "Num Moves": 79}, {"Name": "Volcanion", "Tier": "UU", "Base Stat Total": 600, "Num Moves": 57}, {"Name": "Volcarona", "Tier": "OU", "Base Stat Total": 550, "Num Moves": 67}, {"Name": "Wailord", "Tier": "PU", "Base Stat Total": 500, "Num Moves": 70}, {"Name": "Walrein", "Tier": "PU", "Base Stat Total": 530, "Num Moves": 74}, {"Name": "Watchog", "Tier": "PU", "Base Stat Total": 420, "Num Moves": 83}, {"Name": "Weavile", "Tier": "OU", "Base Stat Total": 510, "Num Moves": 98}, {"Name": "Weezing", "Tier": "PU", "Base Stat Total": 490, "Num Moves": 73}, {"Name": "Whimsicott", "Tier": "NU", "Base Stat Total": 480, "Num Moves": 67}, {"Name": "Whiscash", "Tier": "PU", "Base Stat Total": 468, "Num Moves": 66}, {"Name": "Wigglytuff", "Tier": "PU", "Base Stat Total": 435, "Num Moves": 127}, {"Name": "Wishiwashi", "Tier": "PU", "Base Stat Total": 175, "Num Moves": 43}, {"Name": "Wishiwashi-School", "Tier": "PU", "Base Stat Total": 620, "Num Moves": 43}, {"Name": "Wobbuffet", "Tier": "PU", "Base Stat Total": 405, "Num Moves": 7}, {"Name": "Wormadam", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 58}, {"Name": "Wormadam-Sandy", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 59}, {"Name": "Wormadam-Trash", "Tier": "PU", "Base Stat Total": 424, "Num Moves": 57}, {"Name": "Xatu", "Tier": "NU", "Base Stat Total": 470, "Num Moves": 93}, {"Name": "Xerneas", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 58}, {"Name": "Xurkitree", "Tier": "OU", "Base Stat Total": 570, "Num Moves": 49}, {"Name": "Yanmega", "Tier": "RU", "Base Stat Total": 515, "Num Moves": 68}, {"Name": "Yveltal", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 57}, {"Name": "Zangoose", "Tier": "PU", "Base Stat Total": 458, "Num Moves": 104}, {"Name": "Zapdos", "Tier": "OU", "Base Stat Total": 580, "Num Moves": 69}, {"Name": "Zebstrika", "Tier": "PU", "Base Stat Total": 497, "Num Moves": 54}, {"Name": "Zekrom", "Tier": "Uber", "Base Stat Total": 680, "Num Moves": 70}, {"Name": "Zoroark", "Tier": "UU", "Base Stat Total": 510, "Num Moves": 76}, {"Name": "Zygarde", "Tier": "OU", "Base Stat Total": 600, "Num Moves": 58}, {"Name": "Zygarde-10%", "Tier": "RU", "Base Stat Total": 486, "Num Moves": 43}, {"Name": "Zygarde-Complete", "Tier": "Uber", "Base Stat Total": 708, "Num Moves": 43}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = (' <div class="error" style="color:red;">'
+ ' <p>JavaScript Error: ' + error.message + ' </p>'
+ " <p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback. </p>"
+ ' </div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>
</pre>
</div>
<p>Paste that into a text file, save as <code class="language-plaintext highlighter-rouge">file.html</code>, then open in your browser.
Viola!</p>
<h2 id="exercises">Exercises</h2>
<p>We’ve only just scratched the surface with what we can do with Altair. In this
next portion of the workshop, we’ll try to create some other types of
visualizations.</p>
<p>For data, you can use the pokemon data at this URL:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">csv_url</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
'https://raw.githubusercontent.com/n2cholas/dsc-workshops/master/Intro_to_Interactive_Data_Viz_with_Altair/pokemon-data-cleaned.csv'
</pre>
</div>
<p>Or load data from <code class="language-plaintext highlighter-rouge">vega_datasets</code>, which is a package with datasets well suited
for Altair:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">vega_datasets</span> <span class="kn">import</span> <span class="n">data</span>
<span class="n">cars_df</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">cars</span><span class="p">()</span>
<span class="n">cars_df</span><span class="p">.</span><span class="n">sample</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Name</th>
<th>Miles_per_Gallon</th>
<th>Cylinders</th>
<th>Displacement</th>
<th>Horsepower</th>
<th>Weight_in_lbs</th>
<th>Acceleration</th>
<th>Year</th>
<th>Origin</th>
</tr>
</thead>
<tbody>
<tr>
<th>362</th>
<td>honda prelude</td>
<td>33.7</td>
<td>4</td>
<td>107.0</td>
<td>75.0</td>
<td>2210</td>
<td>14.4</td>
<td>1982-01-01</td>
<td>Japan</td>
</tr>
</tbody>
</table>
</div>
<p>You can find a full list of datasets
<a href="https://github.com/vega/vega-datasets/blob/master/SOURCES.md">here</a>. Check out
the Altair <a href="https://altair-viz.github.io/gallery/index.html">example gallery</a>
for inspiration, or Altair’s <a href="https://github.com/altair-viz/altair_notebooks">tutorial
notebooks</a> for more in depth
explanations.</p>
<h2 id="conclusion--next-steps">Conclusion & Next Steps</h2>
<p>We covered the basics of building interactive visualizations in Altair. For a
more in depth treatment of everything we covered today, check out <a href="https://www.youtube.com/watch?v=ms29ZPUKxbU">Jake
VanderPlas’s workshop at PyCon
2018</a>. As linked before, the
<a href="https://altair-viz.github.io/gallery/index.html">example gallery</a> is a great
place to explore what’s possible with Altair. And of course, the best way to
learn is by doing, so enjoy!</p>Nicholas Vadivelunicholas.vadivelu@gmail.comThrough this post, we’ll explore data using altair, create simple dashboards, and deploy them for others to use. This was heavily inspired by Jake VanderPlas’s workshop at PyCon 2018. If this post piques your interest, definitely check that video out for a longer more in depth version.Comparing Array Partition Algorithms2021-01-11T00:00:00+00:002021-01-11T00:00:00+00:00https://nicholasvadivelu.com/2021/01/11/array-partition<p>Partitioning an array involves moving all elements that satisfy some predicate
to one side of the array. The most common example is partitioning an array of
numbers based on a <em>pivot</em> number, so that all elements on the left side of the
array are less than or equal to the pivot, while all elements on the right are
greater than the pivot. This specific procedure is crucial for <em>quicksort</em>, a
popular and efficient sorting algorithm. The more general partition based on an
arbitrary predicate is useful for a wide range of divide-and-conquer style
problems.</p>
<p>Partitioning an array can be done in-place (i.e. rearranging elements within
the given array without making a copy) using constant space and linear time.
That is, partition uses the same amount of memory regardless of the size
of the input, and its running time increases proportionally to the number of
elements in the given array. The two most common algorithms are Lomuto’s
Partition and Hoare’s Partition (created by Nico Lomuto and Tony Hoare,
respectively). In an <a href="https://youtu.be/fd1_Miy1Clg">NDC 2016 talk</a>, Andrei
Alexandrescu introduces an alternative algorithm which he showed was more
efficient for a variety of data distributions.</p>
<p>This focuses on partition in the context of quicksort. We’ll implement,
visualize, and time these algorithms. Then, we’ll try to tease apart what makes
one slower or faster than the other. All the code to produce the timings,
animations, and plots in this post can be found
<a href="https://github.com/n2cholas/array-partition-comparison">here</a>.</p>
<h2 id="lomutos-partition">Lomuto’s Partition</h2>
<p>Below is a typical implementation of <code class="language-plaintext highlighter-rouge">lomuto_partition</code> as would be used in
quicksort. Our inputs are the array of numbers <code class="language-plaintext highlighter-rouge">arr</code>, the array start index
<code class="language-plaintext highlighter-rouge">lo</code>, and the array end index <code class="language-plaintext highlighter-rouge">hi</code>. Throughout this article, we can assume
<code class="language-plaintext highlighter-rouge">lo=0</code> and <code class="language-plaintext highlighter-rouge">hi=len(arr)-1</code>. For algorithms like quicksort, we want to partition
a contiguous subsection of the array, which is why the start and end indices
are required. This functions returns the index at which the pivot element ends
up in our partitioned array.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">lomuto_partition</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">lo</span><span class="p">,</span> <span class="n">hi</span><span class="p">):</span>
<span class="n">pivot</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">lo</span><span class="p">,</span> <span class="n">hi</span><span class="p">):</span>
<span class="k">if</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span><span class="p">:</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="k">return</span> <span class="n">lo</span>
</code></pre></div></div>
<p>We first choose the rightmost element as the pivot. In practice, we can choose
any element to be the pivot, but for this post, we’ll keep it simple and just
choose either <code class="language-plaintext highlighter-rouge">hi</code> or <code class="language-plaintext highlighter-rouge">lo</code> to be the pivot.</p>
<p>On a high level, we have two indices <code class="language-plaintext highlighter-rouge">j</code> and <code class="language-plaintext highlighter-rouge">lo</code>. We ensure that every element
to the left of <code class="language-plaintext highlighter-rouge">lo</code> is less than or equal to the pivot (invariant A). Also,
ensure every element between <code class="language-plaintext highlighter-rouge">lo</code> and <code class="language-plaintext highlighter-rouge">j</code> is greater than the pivot (invariant
B). Elements to the right of <code class="language-plaintext highlighter-rouge">j</code> are unexplored.</p>
<p>Every time <code class="language-plaintext highlighter-rouge">j</code> encounters an element smaller or equal to the pivot, it swaps it
with the element at <code class="language-plaintext highlighter-rouge">lo</code>. We then increment <code class="language-plaintext highlighter-rouge">j</code> and <code class="language-plaintext highlighter-rouge">lo</code>. This way, <code class="language-plaintext highlighter-rouge">lo</code> is
incremented beyond an element less than or equal to the pivot, maintaining
invariant A. We know the element currently at <code class="language-plaintext highlighter-rouge">j</code> is greater than the pivot.
Why? Since that element was previously between <code class="language-plaintext highlighter-rouge">lo</code> and <code class="language-plaintext highlighter-rouge">j</code>, this implies that
<code class="language-plaintext highlighter-rouge">j</code> passed over it in a previous iteration. If it was passed before but does
not appear to the left of <code class="language-plaintext highlighter-rouge">lo</code> (i.e. was not swapped), that means it is not
less than or equal to the pivot, thus it must be greater, thus maintaining
invariant B.</p>
<p>After the main loop, we swap the pivot from the end into its rightful place
between the two sections, and return the index at which it was placed.</p>
<p>If talking about indices confuses you, here’s a visualization of this algorithm
running on a sample array. The heights of each bar represents the value of the
element at that index. Light gray elements are less than or equal to the pivot,
while black elements are greater. In red two pointers, <code class="language-plaintext highlighter-rouge">lo</code> and <code class="language-plaintext highlighter-rouge">j</code>, are in red,
while the pivot element is in blue.</p>
<p><img src="/assets/images/posts/array-partition/lomuto_animation.gif#center" alt="" /></p>
<p>We see our invariants being held here. We can also observe some extra
work happening: some elements are swapped multiple times unnecessarily. Our
next algorithm avoids this extra work by swapping each element at most once.</p>
<h2 id="hoares-partition">Hoare’s Partition</h2>
<p>Lomuto’s partition maintains two pointers that splits the array into three
sections: less than or equal, greater, and unexplored. Hoare’s partition also
maintains two pointers, but splits the array into less than or equal,
unexplored, and greater.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">hoare_partition</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">lo</span><span class="p">,</span> <span class="n">hi</span><span class="p">):</span>
<span class="n">pivot_ind</span><span class="p">,</span> <span class="n">pivot</span> <span class="o">=</span> <span class="n">hi</span><span class="p">,</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span>
<span class="n">hi</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">while</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span> <span class="ow">and</span> <span class="n">lo</span> <span class="o"><</span> <span class="n">hi</span><span class="p">:</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">while</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">></span> <span class="n">pivot</span> <span class="ow">and</span> <span class="n">lo</span> <span class="o"><</span> <span class="n">hi</span><span class="p">:</span>
<span class="n">hi</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">lo</span> <span class="o"><</span> <span class="n">hi</span><span class="p">:</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">hi</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span><span class="p">:</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">pivot_ind</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">pivot_ind</span><span class="p">]</span>
<span class="k">return</span> <span class="n">lo</span>
</code></pre></div></div>
<p>Our two pointers this time are <code class="language-plaintext highlighter-rouge">lo</code> and <code class="language-plaintext highlighter-rouge">hi</code>. <code class="language-plaintext highlighter-rouge">lo</code> moves from the left to the
right, stopping when an element is greater than the pivot. <code class="language-plaintext highlighter-rouge">hi</code> moves from the
right towards the left, stopping when an element is less than or equal to the
pivot. Once both pointers reach an element violating their side’s condition,
they swap, then proceed.</p>
<p>At the end, we do some clean-up, then swap the pivot into the dividing point
then return that index.</p>
<p>Once again, a visualization:</p>
<p><img src="/assets/images/posts/array-partition/hoare_animation.gif#center" alt="" /></p>
<p>The code is slightly more complex, but this time, no work is wasted: each
element is swapped at most once, which is optimal. However, our code has a lot
of bounds checking, which is wasteful. Our next approach solves this issue.</p>
<h2 id="alexandrescus-partition">Alexandrescu’s Partition</h2>
<p>Hoare’s partition is optimal in terms of swaps, but it does lot of array bounds
checking when incrementing the pointers. Alexandrescu’s partition uses a
<em>sentinel</em> to avoid excessively checking the indices.</p>
<p>Consider this loop from Hoare’s partition:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">while</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span> <span class="ow">and</span> <span class="n">lo</span> <span class="o"><</span> <span class="n">hi</span><span class="p">:</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
</code></pre></div></div>
<p>If we knew for sure that we would encounter an <code class="language-plaintext highlighter-rouge">arr[lo] > pivot</code> before <code class="language-plaintext highlighter-rouge">lo >=
hi</code>, we wouldn’t need to check <code class="language-plaintext highlighter-rouge">lo < hi</code>. To ensure this, we simply plant a
sentinel value at the end of the array which is greater than pivot. This way,
we know the loop will break at that element before <code class="language-plaintext highlighter-rouge">lo</code> goes out of bounds.</p>
<p>Now, the code:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">alexandrescu_partition</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">lo</span><span class="p">,</span> <span class="n">hi</span><span class="p">):</span>
<span class="n">pivot_ind</span><span class="p">,</span> <span class="n">pivot</span> <span class="o">=</span> <span class="n">lo</span><span class="p">,</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="n">old_arr_hi</span><span class="p">,</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">],</span> <span class="n">pivot</span><span class="o">+</span><span class="mi">1</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">while</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span><span class="p">:</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="n">hi</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">while</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">></span> <span class="n">pivot</span><span class="p">:</span>
<span class="n">hi</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">lo</span> <span class="o">>=</span> <span class="n">hi</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span>
<span class="k">if</span> <span class="p">(</span><span class="n">lo</span> <span class="o">==</span> <span class="n">hi</span> <span class="o">+</span> <span class="mi">2</span><span class="p">):</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="n">lo</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o">=</span> <span class="n">old_arr_hi</span>
<span class="k">if</span> <span class="p">(</span><span class="n">pivot</span> <span class="o"><</span> <span class="n">old_arr_hi</span><span class="p">):</span>
<span class="n">lo</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">pivot_ind</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">pivot_ind</span><span class="p">]</span>
<span class="k">return</span> <span class="n">lo</span>
</code></pre></div></div>
<p>We select our pivot as <code class="language-plaintext highlighter-rouge">arr[lo]</code> this time, but it really doesn’t matter.</p>
<p>On the second line, we set the rightmost item to <code class="language-plaintext highlighter-rouge">pivot+1</code>: our sentinel, which
we know is greater than the pivot. We know our leftmost item is less than or
equal to the pivot, since it <em>is</em> our pivot. Now in our main loop, we can
increment our indices without bounds checking! We do the minimal amount of
index checking to ensure our <code class="language-plaintext highlighter-rouge">lo</code> and <code class="language-plaintext highlighter-rouge">hi</code> indices don’t cross.</p>
<p>You may observe something peculiar in the main loop: there are no swaps! The
sentinel on the right side of the array is an element that did not exist in the
original array. We removed the element that was there initially. We call this
spot a <em>vacancy</em>. Now, in our main loop, as we increment our <code class="language-plaintext highlighter-rouge">lo</code> index, and
once we reach an element greater than pivot, we can simply move it to the end
to fill the vacancy. The new vacany is at <code class="language-plaintext highlighter-rouge">lo</code>. We similarly can fill that
vacancy after our <code class="language-plaintext highlighter-rouge">hi</code> loop. In this partition scheme, the vacancy moves towards
the middle of the array. At the end of the procedure, there is some fix-up code
to re-insert the removed element in the right position.</p>
<p>We illustrate the vacancy with a lighter shade of red, while the other index is
the normal shade:</p>
<p><img src="/assets/images/posts/array-partition/alexandrescu_animation.gif#center" alt="" /></p>
<p>This algorithm seems to do some messy clean-up at the end. This is ok: most of
our time is spent in the main loop, so we want to optimize that. The clean-up
only happens once per function call, so it’s negligible for large arrays.</p>
<p>Note that this algorithm is slightly different from the one presented during
the talk. In the talk, the definition of partition allowed elements equal to
the pivot to appear on both the left and right sides. Our requirements are more
strict: we want equal elements only on the left side. Using this stricter
definition allows us to generalize our algorithms to the more general partition
which rearranges element based on a predicate as opposed to a pivot element.
Though, for the Alexandrescu partition, the user would need to provide a
sentinel value that would evaluate false with the predicate, as the algorithm
cannot determine this for some arbitrary and unknown predicate.</p>
<h2 id="timings">Timings</h2>
<p>We time how long it takes to partition arrays of various lengths. These arrays
are NumPy NDArrays filled with 32-bit integers sampled from a discrete uniform
distribution, where the minimum is 0 and maximum is <code class="language-plaintext highlighter-rouge">2*len(arr)</code>. We run these
algorithms 1000 times on random arrays for each array size. The timings were
measured in Python 3.8.5 on an Intel i5-8265U CPU @ 1.60GHz with 8gb of RAM on
Ubuntu 20.04.</p>
<p>A more thorough investigation would simulate a variety of data distributions to
understand these algorithms’ behaviour, but in this post, we’re just interested
in understanding the high level effects of some of the design decisions of
these algorithms.</p>
<p><img src="/assets/images/posts/array-partition/timings.png#center" alt="" /></p>
<p>Nothing surprising here! All these algorithms take time proportional to the
size of the arrays. We see that Alexandrescu’s is fastest across the board by a
<em>bit</em>, followed by Hoare’s, then finally Lomuto’s. The bars represent a 95%
confidence interval of the mean time, so our rankings are statistically
significant (but perhaps not practically significant).</p>
<h2 id="deep-dive">Deep Dive</h2>
<h3 id="number-of-assignments">Number of Assignments</h3>
<p>Recall that Lomuto’s algorithm did extra swaps compared to Hoare’s. We want to
count and see if this is indeed the case on some random arrays. We will count
the number of assignments into the array instead of swaps, since Alexandrescu’s
partition does not do swaps.</p>
<p>In Python, swapping elements is as easy as <code class="language-plaintext highlighter-rouge">arr[lo], arr[hi] = arr[hi],
arr[lo]</code>, but under the hood, this is expanded to something like <code class="language-plaintext highlighter-rouge">tmp =
arr[lo]; arr[lo] = arr[hi]; arr[hi] = tmp</code>, which is a total of 3 assignments,
not 2. For the purposes of our measurements, we’ll only count assignments <em>into
the array</em>, that is, a swap will only be counted as 2 assignments.</p>
<p>The plot below shows the number of assignments into the array for random arrays
of various sizes.</p>
<p><img src="/assets/images/posts/array-partition/num_assigns.png#center" alt="" /></p>
<p>We can see that the Hoare and Alexandrescu lines overlap, giving evidence to
our previous claim that both do the same number of swaps. Lomuto’s, as
expected, does more swaps than the other two algorithms.</p>
<h2 id="number-of-array-element-comparisons">Number of Array Element Comparisons</h2>
<p>Comparisons are needed to determine which side of the pivot a particular
element should go.</p>
<p><img src="/assets/images/posts/array-partition/num_elem_cmp.png#center" alt="" /></p>
<p>All the lines are on top of eachother, indicating that they all do the same
number of comparisons! This makes sense: all the algorithms compare each
element to the pivot exactly once.</p>
<p>Well, this is a slight lie:</p>
<p><img src="/assets/images/posts/array-partition/num_elem_cmp_zoomed.png#center" alt="" /></p>
<p>Alexandrescu’s and Hoare’s do a <em>bit</em> of extra comparing at the end as cleanup,
while the elegant Lomuto’s partition does not.</p>
<h2 id="number-of-array-index-comparisons">Number of Array Index Comparisons</h2>
<p>We saw the main innovation introduced by Alexandrescu’s partition is the
sentinel which eliminated a lot of index checking. Let’s take a look at the
number of index comparisons performed by these algorithms on random arrays.</p>
<p><img src="/assets/images/posts/array-partition/num_ind_cmp.png#center" alt="" /></p>
<p>As expected, Alexandrescu’s has the fewest by a landslide.</p>
<p>In the Python code, you can’t actually see the index comparisons for Lomuto’s
partition. But under the hood, <code class="language-plaintext highlighter-rouge">range</code> needs to do these bounds checks. You can
see that more clearly if you rewrite the algorithm with a <code class="language-plaintext highlighter-rouge">while</code> loop:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">lomuto_partition</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">lo</span><span class="p">,</span> <span class="n">hi</span><span class="p">):</span>
<span class="n">pivot</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span>
<span class="n">j</span> <span class="o">=</span> <span class="n">lo</span>
<span class="k">while</span> <span class="n">j</span> <span class="o"><</span> <span class="n">hi</span><span class="p">:</span>
<span class="k">if</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span><span class="p">:</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">j</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="k">return</span> <span class="n">lo</span>
</code></pre></div></div>
<p>You would expect Hoare’s and Lomuto’s to match, since they do one index check
per index increment/decrement. But actually, Hoare’s gets unchecked index
changes after every swap.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We explored Lomuto’s, Hoare’s, and Alexandrescu’s partition schemes. While
Lomuto’s is the simplest and most elegant, it does the most extra work.
Hoare’s, for a bit more complexity, removes the extra swapping work.
Alexandrescu’s uses a <em>sentinel</em> to avoid bounds checking. It also uses
interesting half-swaps instead of full swaps, further saving work compared to a
swap (due to not needing a temporary). With increasing complexity, we get
improvements in efficiency, which we explained by counting the swaps, element
comparisons, and index comparisons on random arrays.</p>
<p>Since the <a href="https://github.com/n2cholas/array-partition-comparison">code is
available</a>, try things
you think I missed! A good start would be animating or counting operations on
data distributions other than uniformly random integers. For example, a common
real world array distribution is a partially sorted array. Share what you find!</p>
<h2 id="bonus-cython">Bonus: Cython</h2>
<p>We have been doing our investigation in pure Python, which is pretty slow.
Cython will convert your (statically typed) Python code to C, to avoid Python’s
overhead. Here’s an example of this conversion for Lomuto’s in a Jupyter
notebook cell:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">cython</span> <span class="o">-</span><span class="n">a</span>
<span class="n">cimport</span> <span class="n">cython</span>
<span class="n">cimport</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="o">@</span><span class="n">cython</span><span class="p">.</span><span class="n">boundscheck</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="o">@</span><span class="n">cython</span><span class="p">.</span><span class="n">wraparound</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">lomuto_partition_cython</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">ndim</span><span class="o">=</span><span class="mi">1</span><span class="p">]</span> <span class="n">arr</span><span class="p">,</span> <span class="nb">int</span> <span class="n">lo</span><span class="p">,</span> <span class="nb">int</span> <span class="n">hi</span><span class="p">):</span>
<span class="n">cdef</span> <span class="nb">int</span> <span class="n">pivot</span><span class="p">,</span> <span class="n">j</span>
<span class="n">pivot</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">lo</span><span class="p">,</span> <span class="n">hi</span><span class="p">):</span>
<span class="k">if</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o"><=</span> <span class="n">pivot</span><span class="p">:</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="n">lo</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">hi</span><span class="p">],</span> <span class="n">arr</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span>
<span class="k">return</span> <span class="n">lo</span>
</code></pre></div></div>
<p>The output:</p>
<p><img src="/assets/images/posts/array-partition/lomuto_cython_out.png#center" alt="" /></p>
<p>By annotating the types of our parameters and pre-declaring our variables, we
were able to convert this code to C. We can see that our function was
successfully converted with minimal Python interaction (only at the function
call and return). If there was Python interaction, this would slow down our
code as we would have to leave C.</p>
<p>If we had not pre-declared our variables, for example, we would see some Python
interaction, which is suboptimal:</p>
<p><img src="/assets/images/posts/array-partition/lomuto_subopt_cython.png#center" alt="" /></p>
<p>Let’s compare the timings for the three algorithms after Cython compilation.
Additionally, we can compare to NumPy’s built-in partition, since we’re now in
the same order of magnitude of performance. Our experimental set-up is the same
as before, but we do 10,000 runs instead of 1000 to get tighter confidence
intervals.</p>
<p><img src="/assets/images/posts/array-partition/cython_timings.png#center" alt="" /></p>
<p>Woah, our functions run almost 400x faster! Plus, based on our measurements,
our Hoare’s partition implementation runs faster than the native NumPy
implementation (which is written in C). We only beat NumPy here because our
distribution is a uniformly random. NumPy uses an introspective algorithm: it
monitors the progress of the algorithm and can switch partition schemes partway
to ensure good average case performance and optimal worst case performance.
This is crucial with real-world data distributions to ensure consistent
performance, but adds some overhead.</p>
<p>I’m puzzled by why Alexandrescu’s partition ends up being the slowest of the
bunch after Cython compilation, and would love to hear a Cython expert’s
thoughts on this.</p>Nicholas Vadivelunicholas.vadivelu@gmail.comPartitioning an array involves moving all elements that satisfy some predicate to one side of the array. The most common example is partitioning an array of numbers based on a pivot number, so that all elements on the left side of the array are less than or equal to the pivot, while all elements on the right are greater than the pivot. This specific procedure is crucial for quicksort, a popular and efficient sorting algorithm. The more general partition based on an arbitrary predicate is useful for a wide range of divide-and-conquer style problems.How to get your first Undergraduate Research Assistant Role2020-09-28T00:00:00+00:002020-09-28T00:00:00+00:00https://nicholasvadivelu.com/2020/09/28/undergrad-research<p>Research Assistant roles are a great way to gain experience in research and fields that are rare/competitive in an industry role. This guide will focus on part-time assistant roles in <a href="https://uwaterloo.ca/math/undergraduate-research-assistantships-faculty-mathematics">Math</a>, <a href="https://cs.uwaterloo.ca/current-undergraduate-students/research-opportunities/undergraduate-research-assistantship-ura-program">Computer Science</a> or <a href="https://uwaterloo.ca/engineering/ura">Engineering</a> at the University of Waterloo (but hopefully some of the advice will generalize to other faculties/schools). My goal is to supplement the information on UWaterloo’s URA websites with my experience, so please check those out as well.</p>
<p>Some other opportunities I won’t discuss include full-time <a href="https://cs.uwaterloo.ca/current-undergraduate-students/research-opportunities/undergraduate-research-internship-uri-program">Undergraduate Research Internships</a> and the <a href="https://cs.uwaterloo.ca/usra">NSERC Undergraduate Student Research Award</a>.</p>
<p><em>The information in this post is true as of Fall 2020 (specifics about applying/funding may change in the future).</em></p>
<details>
<summary> What is an Undergraduate Research Assistantship (URA)? </summary>
<br /><p>
A URA is a paid part-time research opportunity at the University with a researcher, who is usually a professor. As a first-time URA, you will get a mini-project or tasks to contribute to a research project. This typically involves reading the literature, conducting experiments, implementing methods in literature, implementing your own or others’ ideas, and possibly helping write the final manuscript. If you make a significant contribution, you may end up as the primary author or one of the supporting authors on a publication, which is beneficial for grad school applications or research & development roles in industry!
</p>
</details>
<details>
<summary> Why do a URA? </summary>
<br /><p>
A URA is a unique, paid way to gain technical experience that is relevant to both industry and academia during a school term. During your URA, you will be working on finding solutions to novel problems at the cutting edge of your field. This is a worthy endeavour by itself, but is also a great differentiator when applying for internship roles in the industry, as it shows you are deeply interested in a subject area and are willing to go above and beyond. This will allow you to get interesting roles that you would not have otherwise been qualified for, especially for roles in research & development.
</p><p>
URAs are also a great way to find out if you’re interested in academia (e.g. becoming a professor) or post-undergraduate education (for non course-based programs), since people in those roles spend most of their time conducting research. In addition to the research component, exposure to grad students and professors will give you an opportunity to learn more about their experiences to figure out if it’s right for you. Furthermore, applying to grad school can be very competitive, and demonstrated research experience (+ a publication, if possible) is the best way to show your qualifications for a research-based graduate program. Plus, you will need letters of recommendations to apply, and a letter from a professor with whom you did a URA are much more valuable than a letter from a professor you barely know.
</p>
</details>
<details>
<summary> How much time does a URA take up? </summary>
<br /><p>
The school officially recommends 6 hours per week, though I would suggest dedicating about 10 hours a week (or more if you can!) to really benefit from this opportunity. Depending on the URA, this could involve working in the lab, weekly meetings, and independent work.
</p><p>
You will likely be reading and getting up to speed for a lot of your URA. At first, it took me an entire week or more to get through a single paper, since the content and notation were completely new to me! Just make sure you ask the professor/grad students in your lab questions often so you aren’t stuck for too long (math is notoriously hard to Google). I noticed that undergrads who make significant contributions usually do URAs for more than one term with the same researcher, as it takes a while to gain momentum when doing research (especially when it's your first time).
</p><p>
A URA is manageable with a full course load as long as you limit your other extra curriculars. My strategy for time management is to limit the time I spend on all my involvement (school, extra curriculars, etc) except for one “main” commitment that I let eat up more time as needed. During my URA terms, my “main” commitment was the URA. This helped me get the most out of those experiences, though this definitely is not necessary to have a successful research term.
</p>
</details>
<details>
<summary> How does funding (i.e. getting paid) work? </summary>
<br /><p>
As of Fall 2020, in Engineering, you will receive <span>$900</span> per term. This will typically come from the faculty member’s budget, but if you are one of the first 60 qualified URAs of the term, <span>$250</span> of that <span>$900</span> comes from the Dean’s Office. In CS, you will receive <span>$600</span> from the faculty member and <span>$400</span> from the faculty itself.
</p><p>
If you have the <a href="https://uwaterloo.ca/student-awards-financial-aid/undergraduate-awards/presidents-upper-year-awards">President’s Research Award</a> entrance scholarship, you can claim that <span>$1500</span> in addition to the standard URA salary. Many students who have the President’s Research Award also have the <span>$1500</span> President’s Experiential Award entrance scholarship, which can also be used towards another research role (can't use both at once!). You may be eligible to claim the President’s Award for your URA even if you aren’t eligible for the standard URA funding.
</p>
</details>
<details>
<summary> Who is eligible? </summary>
<br /><p>
In the Faculty of Math (which includes Computer Science), you must be a math/cs student who has completed 2B and has a cumulative average (CAV) of at least 80%. In Engineering, you must be an engineering student who has completed 1B and has a CAV of at least 80%.
</p><p>
These requirements only exist for funding purposes! If your term, CAV, or faculty do not meet the requirements of the URA, you will not receive funding from the faculty. You can still do a URA if the supervisor is willing to fully cover your funding, if you have a President’s Award available, or you are willing to complete the URA on a volunteer basis.
</p>
</details>
<details>
<summary> Am I qualified enough? </summary>
<br /><p>
Without even looking at your resume, yes! URA’s are designed for people who are new to research. However, you still need to demonstrate some basic skills. First, and most importantly, professors want to see that you’re motivated and capable of self-learning. This doesn’t mean you are expected to learn everything by yourself, but rather, you are expected to learn as much as you can independently and come back with specific questions. They also expect you to have the foundational math/computer science/engineering skills required to learn their field, which you can demonstrate through the reasonable marks in your first and second year courses (e.g. in calculus, linear algebra, computer science, etc). Finally, it’s good to have some relevant-ish experience. Software development, hardware engineering, data analysis, and similar skills are all needed to do research (even if the research field is not directly related to those), so having experience in these areas can help you contribute while learning.
</p><p>
Domain knowledge is nice to have, but definitely not necessary for a URA. You’re not expected to be up to speed on a cutting edge area for your very first research role. But, this can definitely give you a leg up, and I find watching lectures or talks online are the best way to get acquainted with a new field. They are less dense and more digestible than papers or textbooks, which is great for beginners.
</p>
</details>
<details>
<summary> How do I figure out what research I want to do? </summary>
<br /><p>
If you figure this out, please let me know, I’m still in the process! Watching talks online, attending reading groups, talking to others in research, and reading survey papers are a great way to introduce yourself to an area of research and see if you want to learn more.
</p><p>
But for your first URA, don’t stress too much about the precise topic of research. Even if you have some idea of what you’re interested in, it’s likely that will change later on. Also, the research style of the professor and lab will affect how much you enjoy and learn from the experience more-so than the topic.
</p><p>
When applying to my first URA, I read almost every computer science professor’s “Research Interests” section (through <a href="https://cs.uwaterloo.ca/about/people/group/49">here</a>) and reached out to every one that I found even somewhat intriguing. For my next round of applications, I even expanded my search to the engineering faculty.
</p><p>
Since many professors will not be able to accomodate a new undergraduate RA, your response rate will likely be pretty low, so don't be afraid to email a ton of professors. During your first chat with those that respond, find out more about their work and why they became interested in it. Perhaps insight into how they came into the field will help you discover your own interests.
</p><p>
Though it will be tiring to reach out to so many people, deciding what you want to do will be much easier when you have a small set of available opportunities rather than trying to pick something from all the research available at the school.
</p>
</details>
<details>
<summary> How do I find a professor to work with? </summary>
<br /><p>
The URA websites list some researchers and potential projects. After reviewing that list, look through the list of researchers in the faculty/area you’re interested in (e.g. <a href="https://cs.uwaterloo.ca/about/people/group/49">here’s one</a> for the Cheriton School of Computer Science, <a href="https://uwaterloo.ca/artificial-intelligence-group/our-people">here’s one</a> for the AI group). For your first pass, read the “Research Interests” section of each researcher’s profile for as many researchers as you can. Then, for those that intrigue you, visit their websites and read about their most recent work to get a sense of their research.
</p><p>
Alternatively, you can attend any public reading groups or talks the professor hosts, which is an excellent way to get to know them and express your interests. Talks can be found on the webpages for various research groups, such as the <a href="https://algcomp.uwaterloo.ca/events/">algorithms & complexity group</a>, <a href="https://uwaterloo.ca/combinatorics-and-optimization/events">combinatorics & optimization department</a>, and <a href="https://uwaterloo.ca/artificial-intelligence-group/events">artificial intelligence group</a>. Some groups also have a mailing list, such as the <a href="https://lists.uwaterloo.ca/mailman/listinfo/ac-other">algorithms & complexity group</a> and <a href="https://uwaterloo.ca/artificial-intelligence-group/mailing-lists">artificial intelligence group</a> (they may not be active, though). Reading groups can be harder to find--I’ve typically heard about these through word of mouth, though some professors list these on their personal websites. Also, talking to grad students who work with a professor is a great way to learn about their research, and they can likely introduce you to the professor. Finally, if you are in a professor’s class, chatting with them during office hours about a URA is a great idea!
</p><p>
After this, email researchers you are interested in working with. I recommend doing this between one week before and one week after the school term starts. There’s no harm in emailing early (it’s probably beneficial!), but you will likely have to wait until the beginning of the term to arrange a URA, as their commitments could be uncertain until the term starts.
</p><p>
Your email body should include a quick introduction about your term/program, why you’re interested in research with them, what your qualifications are (~1-3 sentences), and a request to meet with them to chat about this opportunity. Of course, you won’t have research qualifications if this is your first time doing research, but definitely emphasize your relevant skills in software/hardware, data analysis, etc. If you have a President’s Award available, it’s worth mentioning, as it means they won't necessarily have to fund you themselves. If you are taking or took a class taught by a professor, mention that: it indicates that you have some prerequisite knowledge. Attach both your resume and your transcript to the email. Keep the email brief, professors don’t like reading long emails! Below’s an example:
</p>
<pre>
Subject: Interested in an Undergraduate Research Assistantship
Hello Professor _________,
Hope you’re well! I’m a [term] [program] student interested in doing an Undergraduate Research Assistantship (URA) with you this term. I [read/watched] your recent [paper/talk/workshop], [paper/workshop title], and found it quite relevant to my own interests in ______. Your class on [class the prof taught that you took/are in] was engaging and motivated me to reach out to you. Also, I am eligible to claim a President’s Research Award to fund this URA.
Through my experience as a [role] at [company], I worked on [project] using [tools/tech]. The [engineering/software development/data analysis/machine learning] skills I exercised during this internship are directly applicable to support your research in [area]. Furthermore, I’ve done well in courses on [relevant subject areas], showing that I have the theoretical foundations necessary to succeed in your lab.
Would you be available sometime soon to talk more about a potential URA? I’ve attached my resume and transcript below. Thanks in advance!
Best,
[name]
</pre>
<p>
Professors often miss emails (their inboxes tend to be pretty full, especially at the start of the term), so feel free to bump the email if they don’t respond in about a week. You may also visit them in person to book some time to chat. Don’t feel bad if they don’t respond or if they reject you! A professor will typically only take on a new URA if they have enough time to support a new researcher, so being rejected is more a reflection of the professor’s commitments that term than your abilities.
</p><p>
If the professor has the capacity and willingness to support you, they will invite you for a quick chat about your experiences and potential projects. Don’t be nervous, they won’t grill you on technical concepts! They just want to get to know you better to see if they have a project that’s a good fit for your skill level and interests. At this stage, I would recommend asking about what the expected time commitment is, what prior knowledge the professor expects, what their preferred mode of communication is, who you’ll be working with, what their mentorship style is, and if they have suggestions for reading materials to get started right away or get a better sense of the research area.
</p><p>
If the project and lab are a good fit, the professor will typically let you know during your chat itself or soon after. Then, you can proceed with the URA application process instructions available on the website.
</p><p>
Some professors have a backlog of emails, so they may miss the notification about filling in their portion of the URA form. I prefer to print the form and have the professor sign them in person. The digital president’s research award form is <a href="https://uwaterloo.ca/forms/undergraduate-studies/presidents-research-award-application">here</a>, but you can find a printable version <a href="https://uwaterloo.ca/student-awards-financial-aid/sites/ca.student-awards-financial-aid/files/uploads/files/pres_research_award_app.pdf">here</a> (which you can submit directly to the undergraduate office). The PDF of the engineering URA application is <a href="https://uwaterloo.ca/engineering/sites/ca.engineering/files/uploads/files/ura_fall_2020_application_form_accessible_.pdf">here</a>. For CS, you must register for a URA <a href="https://cs.uwaterloo.ca/ura-registration-form">here</a>, then you will receive a PDF of the physical form. Of course, you can only do things in person after COVID :(.
</p>
</details>
<details>
<summary> Remote URA hunting tips </summary>
<br /><p>
Much of the advice in this post applies to the remote URA search as well. The key challenge is it’s harder to form personal connections while trying to get the URA, since you are limited to email. Many of the reading groups, talks, and office hours still happen virtually over video call. Also, you will have to rely on the digital forms available on the URA websites instead of the PDFs I linked. If your URA is in math, computer science, or other areas that don’t require a physical lab, you will be able to complete the same work (most of the work is independent anyway).
</p><p>
For a remote URA experience, I would pay attention to how quickly a professor replies to email or other forms of contact. Their first response will likely be slow, but if subsequent replies are sporadic as well, that is indicative of how smooth your communication will be for the rest of the term, which makes remote work more difficult. I would advise waiting to do a URA with this professor until you have an in-person term when you can reach them directly. Also, once you start the URA, book regular meetings (perhaps bi-weekly) with other members of the group outside of the lab meetings so you can work with them and get to know them. Since you won’t run into them in person, there’s no way for you to integrate into the lab unless you make this explicit effort.
</p>
</details>
<details>
<summary> My URA experience </summary>
<br /><p>
I have completed a total of two URAs. I applied for a URA for the first time at the beginning of 2nd year, where I emailed about a dozen professors in the Computer Science Faculty who were doing research in Machine Learning (whom I found through the faculty pages linked above). I got about 4 responses. 3 of them said they were not looking for undergraduates for the fall, while the fourth told me to come back once I was a bit more senior. No URA for 2A :(.
</p><p>
The next term (2B), I emailed about 7 more professors, some from the previous term, but others from the Engineering faculty (lots of cool ML work there too). I talked to 2 professors in person, and ultimately chose to do a URA with professor Lin Tan, who was conducting research in machine learning-based program synthesis. At the time, I had some experience in machine learning (one internship in data science), but basically none in research. Since I was not in engineering, I could not get funding directly from the faculty, but I was able to claim my President’s Research Award. I worked closely with one of her PhD students, Thibaud, who gave me an independent project (classifying bugs in code). For the first few weeks, I read papers in the area, attended weekly lab meetings, and got familiar with the data. Afterward, I started conducting experiments by implementing some of Thibaud’s suggestions and methods from papers. A couple weeks later, I started implementing some of my own ideas. In the end, I presented my work from my URA to the rest of the lab. During the URA, I would work in the lab itself for a few hours after the weekly lab meetings, but completed most of my work over weekends.
</p><p>
During the firt term of my third year, I did my second URA. I did not email any professors and instead attended professor Pascal Poupart’s Sum-Product-Network (SPN) reading group. After a couple of weeks in this group, I spoke to him about a potential project with another student. Ultimately, I joined a project on second-order neural network optimization methods with 2 other undergraduate students. This time, I was eligible for the standard URA funding, but claimed my President’s Experiential Award instead. This URA was quite different from the first--the work was more theory focused, and we definitely did a lot more reading than implementation. Also, the project was much more independent, and it was up to us to drive the project. We would meet with Professor Poupart weekly, and during these meetings we would discuss the theory and work through solutions to theoretical issues we were facing.
</p>
</details>
<details>
<summary> Collection of links </summary>
<br /><p>
Below are the links referenced in this article in order of appearance. Note, most of these links are just examples to help you find resources relevant to your area of interest!
</p>
<ul>
<li><a href="https://uwaterloo.ca/math/undergraduate-research-assistantships-faculty-mathematics">Math URA Page</a></li>
<li><a href="https://cs.uwaterloo.ca/current-undergraduate-students/research-opportunities/undergraduate-research-assistantship-ura-program">Computer Science URA Page</a></li>
<li><a href="https://uwaterloo.ca/engineering/ura">Engineering URA Page</a></li>
<li><a href="https://cs.uwaterloo.ca/usra">NSERC Undergraduate Student Research Award</a></li>
<li><a href="https://uwaterloo.ca/student-awards-financial-aid/undergraduate-awards/presidents-upper-year-awards">President’s Research Award</a></li>
<li><a href="https://cs.uwaterloo.ca/about/people/group/49">Cheriton School of Computer Science Faculty Members</a></li>
<li><a href="https://uwaterloo.ca/artificial-intelligence-group/our-people">Artificial Intelligence Group Members</a></li>
<li><a href="https://algcomp.uwaterloo.ca/events/">Algorithms & Complexity Group Events</a></li>
<li><a href="https://uwaterloo.ca/combinatorics-and-optimization/events">Combinatorics & Optimization Department Events</a></li>
<li><a href="https://uwaterloo.ca/artificial-intelligence-group/events">Artificial Intelligence Group Events</a></li>
<li><a href="https://lists.uwaterloo.ca/mailman/listinfo/ac-other">Algorithms & Complexity Group Mailing List</a></li>
<li><a href="https://uwaterloo.ca/artificial-intelligence-group/mailing-lists">Artificial Intelligence Group Mailing Lists</a></li>
<li><a href="https://uwaterloo.ca/forms/undergraduate-studies/presidents-research-award-application">President’s Research Award Digital Application</a></li>
<li><a href="https://uwaterloo.ca/student-awards-financial-aid/sites/ca.student-awards-financial-aid/files/uploads/files/pres_research_award_app.pdf">President’s Research Award PDF Application</a></li>
<li><a href="https://uwaterloo.ca/engineering/sites/ca.engineering/files/uploads/files/ura_fall_2020_application_form_accessible_.pdf">Engineering URA Application PDF</a></li>
<li><a href="https://cs.uwaterloo.ca/ura-registration-form">Computer Science URA Application</a></li>
</ul>
</details>
<p><br />
In all, a URA is a great way to experience research in cutting edge fields and gain skills relevant to academia and industry. You now have the info you need to find a URA–hopefully, I’ll get around to writing about getting the most out of your URA before you start yours. For now, good luck!</p>Nicholas Vadivelunicholas.vadivelu@gmail.comResearch Assistant roles are a great way to gain experience in research and fields that are rare/competitive in an industry role. This guide will focus on part-time assistant roles in Math, Computer Science or Engineering at the University of Waterloo (but hopefully some of the advice will generalize to other faculties/schools). My goal is to supplement the information on UWaterloo’s URA websites with my experience, so please check those out as well.First Steps for Learning Data Science2020-08-30T00:00:00+00:002020-08-30T00:00:00+00:00https://nicholasvadivelu.com/2020/08/30/learn-data-sci<p>This list of resources is designed for someone who has completed high school and would like a practical, hands-on introduction to data science/machine learning, then eventually find a job/internship in the field. There are tons of resources and lists of resources online: this one is short and curated (i.e. very biased), with the goal that a sufficiently motivated beginner can do <strong>everything</strong> on this list within months and be able to apply their skills to real problems.</p>
<h2 id="tldr">TL;DR</h2>
<ol>
<li>Get an overview of data science/machine learning careers from this <a href="https://youtu.be/USMgJOB8wBY">video</a>.</li>
<li>Check out Kaggle for introductory <a href="https://www.kaggle.com/learn/overview">micro-courses</a>. I suggest the <a href="https://www.kaggle.com/learn/python">Python</a>, <a href="https://www.kaggle.com/learn/pandas">Pandas</a>, <a href="https://www.kaggle.com/learn/data-visualization">Data Visualization</a>, and <a href="https://www.kaggle.com/learn/intro-to-machine-learning">Intro to ML</a> courses.</li>
<li>Check out the <a href="https://course.fast.ai/">fast.ai</a> course for a broad, practical introduction to deep learning.</li>
<li>Do some projects (the courses have great suggestions)!</li>
<li>Apply to internships/jobs. Here’s a <a href="https://github.com/n2cholas/resume-checklist">resume checklist</a>, a more detailed <a href="https://docs.google.com/document/d/1rIcPf0HxjhHT9nZPqRGgzvPDn1CoFBWDsfJ-jpbVQyw/edit?usp=sharing">resume guide</a>, and an <a href="https://docs.google.com/document/d/1digEGu1feM6hUmtX6Nas-_J_q-nI5ZjMMTnPHTGc1jA/edit?usp=sharing">interview guide</a>.</li>
</ol>
<h2 id="overview-of-data-science--career-options">Overview of Data Science & Career Options</h2>
<p>To get a sense of what data science is and what careers in data science look like, I presented a workshop on behalf of Data Science Club to incoming UWaterloo Freshman <a href="https://youtu.be/USMgJOB8wBY">here</a>. The video briefly describes data science, machine learning, and artificial intelligence (starting at <a href="https://youtu.be/USMgJOB8wBY?t=279">4:39</a>) as well as careers in the field (<a href="https://youtu.be/USMgJOB8wBY?t=772">12:52</a>). You can also check out the rest of our channel for awesome workshops run by the club.</p>
<h2 id="courses">Courses</h2>
<p>Next, you should take a look at the <a href="https://www.kaggle.com/learn/overview">micro-courses </a>created by Kaggle. These provide a practical and succinct introduction to popular techniques in data science. I would recommend starting with the <a href="https://www.kaggle.com/learn/python">Python</a>, <a href="https://www.kaggle.com/learn/pandas">Pandas</a>, <a href="https://www.kaggle.com/learn/data-visualization">Data Visualization</a>, and <a href="https://www.kaggle.com/learn/intro-to-machine-learning">Intro to ML</a> courses. After those, try a <a href="https://www.kaggle.com/competitions">Kaggle competition</a>! The <a href="https://www.kaggle.com/c/titanic">Titanic </a>and <a href="https://www.kaggle.com/c/house-prices-advanced-regression-techniques">House Prices</a> are popular for beginners. Spend some time applying the techniques you’ve learned, then when you’re stuck, take a look at the kernels (a.k.a. notebooks) that others have created for inspiration. The top-voted kernels for each competition have detailed explanations that will help you level up your skills.</p>
<p>Before spending too much time on Kaggle, take a look at fast.ai. The <a href="https://course.fast.ai/">practical deep learning course</a> is, in my opinion, the best way for beginners to understand deep learning on a high level and apply it to real problems (or Kaggle!). As Jeremy Howard emphasizes in the course, the best way to learn and retain the concepts taught are to take the code and apply it to problems you’re interested in. The only caveat is the fast.ai library from the course is not (yet?) commonly used in industry; however, switching to another library will take no more than a couple of days once you understand the concepts taught in the course.</p>
<h2 id="internships--jobs">Internships & Jobs</h2>
<p>After going through those courses, congrats! You have the skills you need to do solid data science work. The courses I’ve listed provide great suggestions for next steps and projects to pursue to demonstrate your skills. With these projects in your portfolio, you can apply to data science & machine learning jobs/internships. Your resume should tick off every box on this <a href="https://github.com/n2cholas/resume-checklist">checklist</a>, no questions. <a href="https://docs.google.com/document/d/1rIcPf0HxjhHT9nZPqRGgzvPDn1CoFBWDsfJ-jpbVQyw/edit?usp=sharing">Here</a> is a more detailed (and perhaps subjective) guide to creating a great resume and <a href="https://docs.google.com/document/d/1digEGu1feM6hUmtX6Nas-_J_q-nI5ZjMMTnPHTGc1jA/edit?usp=sharing">here</a> are some tips for acing technical interviews (both made by experienced UWaterloo students!). The data science technical interview tips are most relevant for data science internships, but the rest is relevant to all types of tech internships and jobs.</p>
<h2 id="next-steps">Next Steps</h2>
<p>Since this guide is designed for absolute beginners, I did not include any resources for rigorously learning about the math behind data science. While theory is crucial to becoming a great data scientist, I find theory often becomes more engaging and intuitive after being motivated by some hands-on experience. To stay true to the purpose of this post, I won’t provide any links to learn theory–there are tons of high-quality resources just a google search away. Good luck!</p>Nicholas Vadivelunicholas.vadivelu@gmail.comThis list of resources is designed for someone who has completed high school and would like a practical, hands-on introduction to data science/machine learning, then eventually find a job/internship in the field. There are tons of resources and lists of resources online: this one is short and curated (i.e. very biased), with the goal that a sufficiently motivated beginner can do everything on this list within months and be able to apply their skills to real problems.Introduction to Neural Networks in TensorFlow 22019-11-04T00:00:00+00:002019-11-04T00:00:00+00:00https://nicholasvadivelu.com/2019/11/04/intro-to-neural-nets<p>In this workshop, we will learn about Neural Networks and how to build them in TensorFlow 2.</p>
<p>This article provides a summary of the main workshop, which you can watch <a href="https://youtu.be/a_RkE897-Kw">here</a>. <a href="https://colab.research.google.com/github/n2cholas/dsc-workshops/blob/master/Introduction_to_Neural_Networks_with_TensorFlow_2.ipynb">Here</a> is a colab link to run all the code. The colab and article have a section on metrics, which was not covered in the live session.</p>
<h2 id="workshop-overview">Workshop Overview</h2>
<ol>
<li>What is TensorFlow?</li>
<li>Linear Regression</li>
<li>Gradient Descent</li>
<li>Multivariate Logistic Regression</li>
<li>Neural Networks</li>
<li>Intro to tf.keras</li>
</ol>
<h2 id="what-is-machine-learning">What is Machine Learning?</h2>
<ul>
<li><strong>Supervised Learning</strong>: given some input $X$ (called features), predict $y$ (called the target)</li>
<li>Given data, we train a Machine Learning Model</li>
<li>A simple model: $y = mx + b$</li>
<li>Training involves finding the best $m$ and $b$ for the data</li>
<li>Applications include classifying images, generating text, predicting stocks, etc.</li>
</ul>
<h1 id="introduction-to-tensorflow">Introduction to TensorFlow</h1>
<p>TensorFlow is a open source numerical computation library designed for machine learning. Its key advantages over libraries like numpy and scipy are its support for hardware acceleration (GPUs, TPUs, etc), automatic differentiation, and end-to-end ecosystem for designing and deploying machine learning models.</p>
<p>The recent 2.0 update revamped the library for ease of use, making the API feel similar to numpy and PyTorch (another deep learning library).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">tensorflow_version</span> <span class="mf">2.</span><span class="n">x</span> <span class="c1"># Enables version 2.0
</span><span class="kn">import</span> <span class="nn">tensorflow</span> <span class="k">as</span> <span class="n">tf</span>
</code></pre></div></div>
<p>TensorFlow is a library for manipulating <strong>tensors</strong>, which are essentialy multidimensional arrays.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">])</span>
<span class="n">x</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=0, shape=(4,), dtype=int32,
numpy=array([1, 2, 3, 4], dtype=int32)>
</pre>
</div>
<p>You can read all about Tensors in the <a href="https://https://www.tensorflow.org/api_docs/python/tf/Tensor">documentation</a>. The key ideas are they have a data type (dtype), a shape, and a numeric value (numpy array).</p>
<p>Unlike Python lists, you can do <strong>vectorized operations</strong>:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=4, shape=(4,), dtype=int32,
numpy=array([3, 5, 7, 9], dtype=int32)>
</pre>
</div>
<p>Just like numpy, TensorFlow supports <strong>broadcasting</strong>. Here’s a brief example. Suppose you want to add a vector to every row of a matrix:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vec</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">])</span>
<span class="n">matrix</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
<span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span>
<span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">]])</span>
</code></pre></div></div>
<p>With normal lists, you might be inclined to do something like this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">matrix</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="p">:]</span> <span class="c1"># second row of the matrix
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=10, shape=(4,), dtype=int32,
numpy=array([4, 4, 4, 4], dtype=int32)>
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">):</span>
<span class="n">matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="p">:]</span> <span class="o">+=</span> <span class="n">vec</span>
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>----------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-10dabb925653> in <module>()
1 for i in range(3):
----> 2 matrix[i, :] += vec
TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment
</code></pre></div></div>
<p>Oops, you can’t assign values to a Tensor! In general, computations create a new Tensor instead of modifying an existing one. If you need something that is modifable, use a variable. Read more about those <a href="https://www.tensorflow.org/api_docs/python/tf/Variable">here</a></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">matrix</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
<span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span>
<span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">]])</span>
<span class="n">matrix</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Variable 'Variable:0' shape=(3, 4) dtype=int32, numpy=
array([[1, 1, 1, 1],
[4, 4, 4, 4],
[5, 5, 5, 5]], dtype=int32)>
</pre>
</div>
<p>Now, back to adding this vector to the matrix. If you add them directly, broadcasting will see that the all the dimensions of <code class="language-plaintext highlighter-rouge">vec</code> and <code class="language-plaintext highlighter-rouge">matrix</code> match except for one, so it will duplicate vec along that dimension so the addition works.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">matrix</span> <span class="o">+</span> <span class="n">vec</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=26, shape=(3, 4), dtype=int32, numpy=
array([[2, 3, 4, 5],
[5, 6, 7, 8],
[6, 7, 8, 9]], dtype=int32)>
</pre>
</div>
<p>Now we can assign this new value to matrix:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">matrix</span><span class="p">.</span><span class="n">assign</span><span class="p">(</span><span class="n">matrix</span> <span class="o">+</span> <span class="n">vec</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Variable 'UnreadVariable' shape=(3, 4) dtype=int32, numpy=
array([[2, 3, 4, 5],
[5, 6, 7, 8],
[6, 7, 8, 9]], dtype=int32)>
</pre>
</div>
<p><a href="https://scipy-lectures.org/intro/numpy/operations.html#broadcasting">Here’s</a> a more detailed overview of broadcasting.</p>
<p>We can create scalar tensors and variables:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">x</span> <span class="o">+</span> <span class="n">v</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=39, shape=(), dtype=int32, numpy=1>
</pre>
</div>
<p>Take a few minutes to explore Tensors and Variables. Create some, play with them, and use the documentation to figure out what they can and can’t do!</p>
<h2 id="introduction-to-linear-regression">Introduction to Linear Regression</h2>
<p>We’re going to start by fitting a line ($y = mx + b$) to some simulated data in TensorFlow. Suppose have some data:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="nb">range</span><span class="p">(</span><span class="mf">1.</span><span class="p">,</span> <span class="mf">5.</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">)</span> <span class="c1"># ensure all the inputs are floats!
</span><span class="n">x</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=43, shape=(40,), dtype=float32, numpy=
array([1. , 1.1 , 1.2 , 1.30000, 1.40000, 1.50000,
1.60000, 1.70000, 1.80000, 1.90000, 2.00000, 2.10000,
2.2 , 2.3 , 2.39999, 2.49999, 2.59999, 2.69999,
2.79999, 2.89999, 2.99999, 3.09999, 3.19999, 3.29999,
3.39999, 3.49999, 3.59999, 3.69999, 3.79999, 3.89999,
3.99999, 4.09999, 4.19999, 4.29999, 4.39999, 4.49999,
4.59999, 4.69999, 4.79999, 4.89999], dtype=float32)>
</pre>
</div>
<p>Above we’ve created our x values, which is our <strong>explanatory variable</strong>. We will simulate a <strong>response variable</strong> y, which has the relationship $y = 3.5x - 1$, plus some noise.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y</span> <span class="o">=</span> <span class="mf">3.5</span><span class="o">*</span><span class="n">x</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">tf</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="mi">40</span><span class="p">,),</span> <span class="n">minval</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">maxval</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
<span class="n">y</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=55, shape=(40,), dtype=float32, numpy=
array([ 1.5081716, 3.4402354, 3.565304 , 2.9521132, 4.642995 ,
5.1984725, 4.033718 , 4.244085 , 5.6146545, 6.6339474,
6.4838257, 6.9260926, 6.266905 , 6.4089746, 6.5717545,
6.8176184, 7.19166 , 9.247049 , 7.9582567, 10.14625 ,
8.848628 , 10.280046 , 9.729949 , 10.760101 , 11.438638 ,
11.2754 , 11.156017 , 11.16319 , 12.735874 , 13.418887 ,
12.87348 , 13.070494 , 13.1910925, 13.565499 , 14.655623 ,
14.032754 , 15.643642 , 16.414732 , 16.290714 , 16.515282 ],
dtype=float32)>
</pre>
</div>
<p>Let’s see how our data looks:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="o">%</span> <span class="n">matplotlib</span> <span class="n">inline</span>
<span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-neural-nets/Introduction_to_Neural_Networks_with_TensorFlow_2_28_1.png#center" alt="png" /></p>
<p>When we fit a linear model to data, we want to find the values of <strong>parameters</strong> $m$ and $b$ to make our line best represent our data. Let’s createt these variables first:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">m</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span> <span class="c1"># explicitly set the data type, because the initial value is an integer
</span><span class="n">b</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
</code></pre></div></div>
<p>Let’s see our line looks before fitting it to data:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y_pred</span> <span class="o">=</span> <span class="n">x</span><span class="o">*</span><span class="n">m</span> <span class="o">+</span> <span class="n">b</span> <span class="c1"># notice y is a vector, we are doing a vectorized operation here on all the entries of x
</span><span class="n">y_pred</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=97, shape=(40,), dtype=float32, numpy=
array([1. , 1.1 , 1.2 , 1.3000001, 1.4000001, 1.5000001,
1.6000001, 1.7000002, 1.8000002, 1.9000002, 2.0000002, 2.1000001,
2.2 , 2.3 , 2.3999999, 2.4999998, 2.5999997, 2.6999996,
2.7999995, 2.8999994, 2.9999993, 3.0999992, 3.199999 , 3.299999 ,
3.399999 , 3.4999988, 3.5999987, 3.6999986, 3.7999985, 3.8999984,
3.9999983, 4.0999985, 4.1999984, 4.2999983, 4.399998 , 4.499998 ,
4.599998 , 4.699998 , 4.799998 , 4.8999977], dtype=float32)>
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">plt</span><span class="p">.</span><span class="n">scatter</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="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-neural-nets/Introduction_to_Neural_Networks_with_TensorFlow_2_33_1.png#center" alt="png" /></p>
<p>Our line doesn’t look great. But how do we know when our model is doing well? We will define a numeric measure of how poorly our model is doing. In machine learning, this is called a <strong>loss function</strong>. The larger our loss, the worse our model is.</p>
<p>For regression, a common loss function is <strong>mean squared error</strong> (MSE):</p>
<p>MSE = $\frac{1}{N}\sum^N_{i=1} (y_{i, true} - y_{i, predicted})^2$</p>
<p>Our goal is to minimize this loss function.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">mse</span><span class="p">(</span><span class="n">y_true</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">):</span>
<span class="c1"># TensorFlow has this function built in: tf.keras.losses.MSE(y_true, y_pred)
</span> <span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">((</span><span class="n">y_true</span> <span class="o">-</span> <span class="n">y_pred</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mse</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span> <span class="c1"># want to minimize this value!
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=182, shape=(), dtype=float32, numpy=49.60046>
</pre>
</div>
<p>For linear regression, we know there’s a closed form solution. let’s just compute that:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sxx</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">((</span><span class="n">x</span> <span class="o">-</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">x</span><span class="p">))</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="n">sxy</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">((</span><span class="n">x</span> <span class="o">-</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">x</span><span class="p">))</span><span class="o">*</span><span class="p">(</span><span class="n">y</span> <span class="o">-</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">y</span><span class="p">)))</span>
<span class="n">m</span><span class="p">.</span><span class="n">assign</span><span class="p">(</span><span class="n">sxy</span><span class="o">/</span><span class="n">sxx</span><span class="p">)</span>
<span class="n">b</span><span class="p">.</span><span class="n">assign</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="o">-</span> <span class="n">m</span><span class="o">*</span><span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">x</span><span class="o">*</span><span class="n">m</span> <span class="o">+</span> <span class="n">b</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">mse</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">).</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 0.4125025272369385
</pre>
</div>
<p>Our loss went down (and is minimized, because this is a closed form solution)! Let’s check out how this looks graphically:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">plt</span><span class="p">.</span><span class="n">scatter</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="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'m: </span><span class="si">{</span><span class="n">m</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> b: </span><span class="si">{</span><span class="n">b</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
m: 3.5368335247039795 b: -1.110854148864746
</pre>
</div>
<p><img src="/assets/images/posts/intro-to-neural-nets/Introduction_to_Neural_Networks_with_TensorFlow_2_40_1.png#center" alt="png" /></p>
<p>Much better! Our parameter values are also very close to the true relationship between $x$ and $y$.</p>
<h2 id="what-if-we-didnt-have-a-closed-form-gradient-descent">What if we didn’t have a closed form? Gradient Descent!</h2>
<p>We have a function $L$ (our loss function, MSE) that we want to minimize by changing our parameters $m$ and $b$. The partial derivative $\frac{\partial L}{\partial m}$ represents the direction of steepest ascent with respect to $m$. If we travel in the direction of the $-\frac{\partial L}{\partial m}$, we are travelling in a direction where our loss function gets smaller. By taking small steps and computing the direction of the derivative at each step, we can slowly make progress towards a local minima. In particular, at every step, here is the update rule:</p>
<p>$m_{k+1} = m_k - \alpha\frac{\partial L}{\partial m}$</p>
<p>$b_{k+1} = b_k - \alpha\frac{\partial L}{\partial b}$</p>
<p>$\alpha$ is our <strong>learning rate</strong>. Typically, this is a value < 1 so we don’t take steps that are too large. If our steps are too large, we may never reach the minimum (might jump over the minimum, or diverge altogether). A <strong>gradient</strong> is a vector of partial derivatives of our parameters. Concretely, let $\theta = [m, b]^T$. we can rewrite the above expression concisely as follows.</p>
<p>$\theta_{k+1} = \theta_k - \alpha\nabla_\theta L = \begin{bmatrix} m_k \ b_k \end{bmatrix} - \alpha \begin{bmatrix} \frac{\partial L}{\partial m} \ \frac{\partial L}{\partial b} \end{bmatrix}$</p>
<p>Gradient Descent has some drawbacks. It’s much slower than a closed form solution. Also, if we have a loss function that isn’t <strong>convex</strong>, it could have multiple minima, so our algorithm may converge to a minimum that isn’t the global minimum.</p>
<p>The image below shows the value of an example loss function $J(\theta_0, \theta_1)$ (which could be MSE) plotted against $\theta_0$ and $\theta_1$ (which could be $m$ and $b$).</p>
<p><img src="https://hackernoon.com/hn-images/1*f9a162GhpMbiTVTAua_lLQ.png#center" alt="alt text" /></p>
<p>For linear regression, we know that the loss function is convex (unlike the picture above), though for machine learning models in general, this is not true.</p>
<p>Let’s use gradient descent to fit our linear model.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">m</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
<span class="n">m</span><span class="p">,</span> <span class="n">b</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
(<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>,
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>)
</pre>
</div>
<p>We want to iteratively update our parameters in the direction of the negative gradient. TensorFlow supports automatic differentiation, so let’s take advantage of that. We use something called a <code class="language-plaintext highlighter-rouge">GradientTape</code> to track computations in TensorFlow. After tracking them, we are able to differentiate wirth respect to them.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">x</span><span class="o">*</span><span class="n">m</span> <span class="o">+</span> <span class="n">b</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">mse</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="p">[</span><span class="n">m</span><span class="p">,</span> <span class="n">b</span><span class="p">])</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
[<tf.Tensor: id=354, shape=(), dtype=float32, numpy=-44.360188>,
<tf.Tensor: id=347, shape=(), dtype=float32, numpy=-12.745608>]
</pre>
</div>
<p>The result is the value of the partials with respect to the variables. With GradientTape, computations with Variables are automatically tracked. If you want to differentiate with respect to Tensors, you have to use <code class="language-plaintext highlighter-rouge">tape.watch(tensor)</code>. We won’t cover that in this workshop, but you can check that out <a href="https://www.tensorflow.org/tutorials/customization/autodiff">here</a>.</p>
<p>Now we can write our training loop. We will take 100 steps with a learning rate of 0.05. Here’s how that looks:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">lr</span> <span class="o">=</span> <span class="mf">0.05</span> <span class="c1"># learning rate
</span>
<span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">x</span><span class="o">*</span><span class="n">m</span> <span class="o">+</span> <span class="n">b</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">mse</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="p">[</span><span class="n">m</span><span class="p">,</span> <span class="n">b</span><span class="p">])</span>
<span class="n">m</span><span class="p">.</span><span class="n">assign_sub</span><span class="p">(</span><span class="n">lr</span><span class="o">*</span><span class="n">gradient</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">b</span><span class="p">.</span><span class="n">assign_sub</span><span class="p">(</span><span class="n">lr</span><span class="o">*</span><span class="n">gradient</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">10</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 49.600460052490234
Loss: 0.717918336391449
Loss: 0.6513835191726685
Loss: 0.5993430018424988
Loss: 0.558639645576477
Loss: 0.5268036127090454
Loss: 0.5019029378890991
Loss: 0.482427179813385
Loss: 0.46719399094581604
Loss: 0.4552793502807617
</pre>
</div>
<p>Our loss went down, nice! Let’s check out the parameter values and the a graph:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">scatter</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="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'m: </span><span class="si">{</span><span class="n">m</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> b: </span><span class="si">{</span><span class="n">b</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
m: 3.387526035308838 b: -0.6091350317001343
</pre>
</div>
<p><img src="/assets/images/posts/intro-to-neural-nets/Introduction_to_Neural_Networks_with_TensorFlow_2_49_1.png#center" alt="png" /></p>
<p>Our code is clean and simple for the simple linear regression case, but it does not scale well. Let’s use some classes and objects to clean things up a bit.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Linear</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">m</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">b</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">trainable_variables</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">m</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">b</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span> <span class="c1"># assume x is a row vector
</span> <span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">m</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">b</span>
</code></pre></div></div>
<p>The class above is a callable. When you call it with some input, it’ll apply the linear function.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">lr</span> <span class="o">=</span> <span class="mf">0.05</span> <span class="c1"># learning rate
</span>
<span class="n">linear_model</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">()</span>
<span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">mse</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="k">for</span> <span class="n">partial</span><span class="p">,</span> <span class="n">variable</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">):</span>
<span class="n">variable</span><span class="p">.</span><span class="n">assign_sub</span><span class="p">(</span><span class="n">lr</span><span class="o">*</span><span class="n">partial</span><span class="p">)</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">10</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 49.600460052490234
Loss: 0.717918336391449
Loss: 0.6513835191726685
Loss: 0.5993430018424988
Loss: 0.558639645576477
Loss: 0.5268036127090454
Loss: 0.5019029378890991
Loss: 0.482427179813385
Loss: 0.46719399094581604
Loss: 0.4552793502807617
</pre>
</div>
<p>Let’s also encapsulate our gradient update into an object too, to make things even cleaner:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">GradientDescentOptimizer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lr</span><span class="o">=</span><span class="mf">0.05</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">lr</span> <span class="o">=</span> <span class="mf">0.05</span>
<span class="k">def</span> <span class="nf">apply_gradients</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">grads_and_vars</span><span class="p">):</span>
<span class="k">for</span> <span class="n">grad</span><span class="p">,</span> <span class="n">var</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span> <span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">):</span>
<span class="n">var</span><span class="p">.</span><span class="n">assign_sub</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">lr</span><span class="o">*</span><span class="n">grad</span><span class="p">)</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">linear_model</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">()</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">GradientDescentOptimizer</span><span class="p">(</span><span class="n">lr</span><span class="o">=</span><span class="mf">0.05</span><span class="p">)</span>
<span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">mse</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">10</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 49.600460052490234
Loss: 0.717918336391449
Loss: 0.6513835191726685
Loss: 0.5993430018424988
Loss: 0.558639645576477
Loss: 0.5268036127090454
Loss: 0.5019029378890991
Loss: 0.482427179813385
Loss: 0.46719399094581604
Loss: 0.4552793502807617
</pre>
</div>
<p>TensorFlow actually gives us exactly this optimizer (with some more bells and whistles, of course):</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">tensorflow.keras.optimizers</span> <span class="kn">import</span> <span class="n">SGD</span>
<span class="n">linear_model</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">()</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">SGD</span><span class="p">(</span><span class="n">lr</span><span class="o">=</span><span class="mf">0.05</span><span class="p">)</span>
<span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">mse</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">10</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 49.600460052490234
Loss: 0.717918336391449
Loss: 0.6513835191726685
Loss: 0.5993430018424988
Loss: 0.558639645576477
Loss: 0.5268036127090454
Loss: 0.5019029378890991
Loss: 0.482427179813385
Loss: 0.46719399094581604
Loss: 0.4552793502807617
</pre>
</div>
<p>SGD stands for Stochastic Gradient Descent. It essentially exactly the same thing as our optimizer. We’ll talk about it in more detail later.</p>
<h2 id="what-if-we-have-multiple-inputs">What if we have multiple inputs?</h2>
<p>$y = \vec x^T \vec w + b $</p>
<p>Expanded:</p>
<p>$y = x_1w_1 + x_2w_2 + …. + x_mw_m + b$</p>
<p><br /></p>
<h2 id="what-if-we-have-multiple-outputs-as-well">What if we have multiple outputs as well?</h2>
<p>$\vec y = x^T \vec W + \vec b$</p>
<p>Expanded:</p>
<p>$y_1 = x_1W_{1,1} + x_2W_{2,1} + … + x_kW_{1,m} + b_1$</p>
<p>$\dots$</p>
<p>$y_n = x_1W_{k,1} + x_2W_{k,2} + … + x_kW_{k,m} + b_k$</p>
<p><br /></p>
<p>Let’s update our linear class to support multiple inputs and ouputs.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Linear</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">input_length</span><span class="p">,</span> <span class="n">output_length</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">W</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">ones</span><span class="p">([</span><span class="n">input_length</span><span class="p">,</span> <span class="n">output_length</span><span class="p">]))</span>
<span class="bp">self</span><span class="p">.</span><span class="n">b</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">output_length</span><span class="p">))</span>
<span class="bp">self</span><span class="p">.</span><span class="n">trainable_variables</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">W</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">b</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span> <span class="c1"># assume x is a row vector
</span> <span class="k">return</span> <span class="n">x</span> <span class="o">@</span> <span class="bp">self</span><span class="p">.</span><span class="n">W</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">b</span> <span class="c1"># @ is the matrix multiplication operator
</span></code></pre></div></div>
<p>TensorFlow gives us almost exactly this in <code class="language-plaintext highlighter-rouge">tf.keras.layers.Dense</code>. For now, we will use our class for more transparency.</p>
<h2 id="mnist">MNIST</h2>
<p>MNIST is a dataset of handwritten digits from 1 to 9, originally published by Yann Lecun, Corinna Cortes, Christopher J.C. Burges. Let’s check it out:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">),</span> <span class="n">_</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">datasets</span><span class="p">.</span><span class="n">mnist</span><span class="p">.</span><span class="n">load_data</span><span class="p">()</span>
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
<span class="n">y</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16386, shape=(), dtype=uint8, numpy=1>
</pre>
</div>
<p><img src="/assets/images/posts/intro-to-neural-nets/Introduction_to_Neural_Networks_with_TensorFlow_2_67_1.png#center" alt="png" /></p>
<h4 id="exercise">Exercise:</h4>
<ol>
<li>What’s the shape of each image?</li>
<li>How many images do we have in this dataset?</li>
<li>How many of each class do we have?</li>
<li>What’s are the datatypes?</li>
</ol>
<p>Try running the code and figuring this out on your own! Now the answers…</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span><span class="p">.</span><span class="n">shape</span><span class="p">,</span> <span class="n">y</span><span class="p">.</span><span class="n">shape</span> <span class="c1"># 28*28 images, 60 000 images
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
(TensorShape([60000, 28, 28]), TensorShape([60000]))
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Number of </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s">: </span><span class="si">{</span><span class="n">tf</span><span class="p">.</span><span class="n">reduce_sum</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">y</span> <span class="o">==</span> <span class="n">i</span><span class="p">,</span> <span class="n">tf</span><span class="p">.</span><span class="n">int32</span><span class="p">)).</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Number of 0: 5923
Number of 1: 6742
Number of 2: 5958
Number of 3: 6131
Number of 4: 5842
Number of 5: 5421
Number of 6: 5918
Number of 7: 6265
Number of 8: 5851
Number of 9: 5949
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span><span class="p">.</span><span class="n">dtype</span><span class="p">,</span> <span class="n">y</span><span class="p">.</span><span class="n">dtype</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
(tf.uint8, tf.uint8)
</pre>
</div>
<h4 id="preprocessing">Preprocessing</h4>
<p>We’ll work with just 500 examples, so our code runs faster. We also want to normalize our image values so they’re between 0 and 1. This makes makes training our models easier, since the scale of our gradients and parameters are more predictable.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">[:</span><span class="mi">500</span><span class="p">],</span> <span class="n">y</span><span class="p">[:</span><span class="mi">500</span><span class="p">]</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span> <span class="o">/</span> <span class="mf">255.0</span>
</code></pre></div></div>
<p>When we did regression, we assumed our response was a continuous variable. Now, our response is one of 9 categories. It doesn’t make sense to fit a line to discrete values from 1 to 9, so we will do something called <strong>one hot encoding</strong>.</p>
<p>Essentially, instead of 1 number representing the category, we have a vector of size 10. This vector has 0s everywhere, except a 1 indicating which category the example corresponds to. <a href="https://machinelearningmastery.com/why-one-hot-encode-data-in-machine-learning/">Here</a>’s a great article about why we one hot encode.</p>
<p>Intuitively, this vector represents a probability distribution. In our training data, if our example is a 1, there is a 100% chance it is a 1. So, vec[1] = 100%, while the rest = 0. We will create a model that will predict probabilities for each digit. Our model’s prediction is whichever digit it assigned the highest probability.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">one_hot</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">y</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16451, shape=(500, 10), dtype=float32, numpy=
array([[0., 0., 0., ..., 0., 0., 0.],
[1., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 1., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 1., 0.]], dtype=float32)>
</pre>
</div>
<p>We will also reshape our explanatory variable from a 28x28 image to a 28*28 long vector, so we can continue to use the techniques we have developed.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">28</span><span class="o">*</span><span class="mi">28</span><span class="p">))</span>
<span class="n">x</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16453, shape=(500, 784), dtype=float32, numpy=
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], dtype=float32)>
</pre>
</div>
<p>Now our dataset contains 60,000 vectors of length 784.</p>
<p>For easy reuse, we’ll define a function that does all this for us, in case we need it again:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">preprocess</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="c1"># Converts numpy arrays to preprocessing tensors
</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">tf</span><span class="p">.</span><span class="n">convert_to_tensor</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">28</span><span class="o">*</span><span class="mi">28</span><span class="p">))</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span> <span class="o">/</span> <span class="mf">255.0</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">one_hot</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="k">return</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
</code></pre></div></div>
<p>Let’s jump right into it with our linear model!</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16453, shape=(500, 784), dtype=float32, numpy=
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], dtype=float32)>
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">linear_model</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">(</span><span class="n">input_length</span><span class="o">=</span><span class="mi">784</span><span class="p">,</span> <span class="n">output_length</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</code></pre></div></div>
<p>Broadcasting is what keeps our code so concise. Even though there are 500 training examples, broadcasting will do the matrix multplication on each row of the input matrix (i.e. each example). The output has one output vector per row:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16475, shape=(500, 10), dtype=float32, numpy=
array([[107.94119 , 107.94119 , 107.94119 , ..., 107.94119 , 107.94119 , 107.94119],
[121.94121 , 121.94121 , 121.94121 , ..., 121.94121 , 121.94121 , 121.94121],
[ 76.247055, 76.247055, 76.247055, ..., 76.247055, 76.247055, 76.247055],
...,
[ 81.074524, 81.074524, 81.074524, ..., 81.074524, 81.074524, 81.074524],
[ 71.69804 , 71.69804 , 71.69804 , ..., 71.69804 , 71.69804 , 71.69804 ],
[108.50588 , 108.50588 , 108.50588 , ..., 108.50588 , 108.50588 , 108.50588]],
dtype=float32)>
</pre>
</div>
<p>Great…but we wanted our outputs to represent a probability distribution. We need to normalize the output of model so the vector represents a probability distribution.</p>
<p>We are doing what’s called <strong>multiclass logistic regression</strong>. The current outputs of our linear model are called <strong>logits</strong>. To get the probabilities, we normalize our output using a function called a <strong>softmax</strong>. Let $\vec y = [y_1, y_2, …. y_k]$ be our output vector:</p>
\[softmax(\vec y) = \left\{\frac{\exp(y_i)}{\sum_{j=1}^k \exp(y_j)}\right\}_{i=1...k}\]
<p>This forces the sum of the elements to equal 1 (like a probability). You’ll notice we don’t just normalize–we exponentiate then normalize. Intuitively, an exponent makes large values increase more than it does small values. If the model outputs small differences between the classes, this function will make one entry in the vector large and close to one, and the rest close to 0. This will make it easier for our model’s output to match the one-hot encoded ground truth.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">softmax</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">exp</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">/</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_sum</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">exp</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="n">softmax</span><span class="p">(</span><span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16484, shape=(500, 10), dtype=float32, numpy=
array([[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[nan, nan, nan, ..., nan, nan, nan]], dtype=float32)>
</pre>
</div>
<p>Yikes, looks like there’s some numerical overflow in our softmax. We’ll use the built in one to avoid this (there are some tricks to make it numerically stable):</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y_pred</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="n">y_pred</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16489, shape=(500, 10), dtype=float32, numpy=
array([[0.1, 0.1, 0.1, ..., 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, ..., 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, ..., 0.1, 0.1, 0.1],
...,
[0.1, 0.1, 0.1, ..., 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, ..., 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, ..., 0.1, 0.1, 0.1]], dtype=float32)>
</pre>
</div>
<p>Great, let’s check that our probability vectors add up to 1, just like we want.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tf</span><span class="p">.</span><span class="n">reduce_sum</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16491, shape=(500,), dtype=float32, numpy=
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1.], dtype=float32)>
</pre>
</div>
<p>Since we are doing classification, we can compute accuracy! Let’s do that:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">accuracy</span><span class="p">(</span><span class="n">y_true</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">):</span>
<span class="n">equal_preds</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">argmax</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="n">tf</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">argmax</span><span class="p">(</span><span class="n">y_true</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">equal_preds</span><span class="p">,</span> <span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">))</span>
<span class="n">accuracy</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16499, shape=(), dtype=float32, numpy=0.1>
</pre>
</div>
<p>As we’d expect, our untrained model has a 10% accuracy, which is as accurate as one would be when randomly guessing.</p>
<p>At this point, you might think we’re going to maximize accuracy via gradient descent. Unfortunately, this is not possible, since accuracy is not differentiable. Instead, we are going to go back to thinking about our outputs as a probability distribution. We use a loss called <strong>categorical crossentropy</strong>. This essentially measures how far our output vector is from the target vector (our one hot encoded labels). Suppose our prediction/true values are of the form $\vec y = [y_1, y_2, …, y_k]$ (i.e. we have k classes).</p>
<p>$L(\vec y_{true}, \vec y_{pred}) = - \sum^k_{i=1} y_{i, true}\log(y_{i, prediction})$</p>
<p>Notice that $y_{i, true} = 0$ for all values except for $i = $true class. Also, $\log(y_{i, prediction}) = 0$ when $y_{i, prediction} = 1$. When it’s smaller, the value is negative, so our loss is positive. Essentially, this loss 0 when our model output exactly matches the training data, which is what we want.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">categorical_crossentropy</span><span class="p">(</span><span class="n">y_true</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">):</span>
<span class="k">return</span> <span class="o">-</span><span class="n">tf</span><span class="p">.</span><span class="n">reduce_sum</span><span class="p">(</span><span class="n">y_true</span><span class="o">*</span><span class="n">tf</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">y_pred</span><span class="p">),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>
<p>TensorFlow gives us this function too: <code class="language-plaintext highlighter-rouge">tf.keras.losses.categorical_crossentropy</code>. We can use ours and TensorFlow’s interchangeably.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">categorical_crossentropy</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span> <span class="c1"># this outputs the cross entropy per example
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
<tf.Tensor: id=16504, shape=(500,), dtype=float32, numpy=
array([2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851, 2.3025851,
2.3025851, 2.3025851], dtype=float32)>
</pre>
</div>
<p>Now you have all the tools to write the training loop for logistic regression. Try it before looking at the solution below!</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.1</span><span class="p">)</span>
<span class="n">linear_model</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">(</span><span class="mi">28</span><span class="o">*</span><span class="mi">28</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1000</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">linear_model</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">categorical_crossentropy</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span>
<span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 2.3025851249694824 Accuracy: 0.10000000149011612
Loss: 0.4364985227584839 Accuracy: 0.9039999842643738
Loss: 0.29362964630126953 Accuracy: 0.9440000057220459
Loss: 0.22477126121520996 Accuracy: 0.9660000205039978
Loss: 0.18162311613559723 Accuracy: 0.9819999933242798
Loss: 0.1515568494796753 Accuracy: 0.9860000014305115
Loss: 0.12939059734344482 Accuracy: 0.9919999837875366
Loss: 0.11246717721223831 Accuracy: 0.9980000257492065
Loss: 0.099213607609272 Accuracy: 1.0
Loss: 0.08861198276281357 Accuracy: 1.0
</pre>
</div>
<p>Wow, our model’s doing really well! Let’s take a look at a prediction:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y_pred</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">numpy</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([7.2486359e-03, 8.7252660e-03, 1.6632091e-02, 6.6710129e-02,
2.4541716e-05, 8.8565266e-01, 1.4892247e-03, 4.6367473e-03,
7.0132478e-03, 1.8675643e-03], dtype=float32)
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">numpy</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype=float32)
</pre>
</div>
<p>Nice, for this example, our model’s outputting a probability of 75% for the most likely class, which is correct.</p>
<p>But our results are misleading. We are evaluating our model on the same data we trained it on. This is the equivalent of teaching a student some concepts, then testing them on it, BUT giving them the test as prep material. We want to evaluate our model on new examples.</p>
<p>In machine learning, we call this a <strong>test set</strong>. We do not train our model on this data, we only evaluate our model. Typically, we do a random split of our dataset to get a train/test split. MNIST already has this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">),</span> <span class="p">(</span><span class="n">x_test</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">datasets</span><span class="p">.</span><span class="n">mnist</span><span class="p">.</span><span class="n">load_data</span><span class="p">()</span>
<span class="n">x_test</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">preprocess</span><span class="p">(</span><span class="n">x_test</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">linear_model</span><span class="p">(</span><span class="n">x_test</span><span class="p">))</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">categorical_crossentropy</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y_test</span><span class="p">,</span>
<span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 0.5398113131523132 Accuracy: 0.8337000012397766
</pre>
</div>
<p>Not great. Our model has <strong>overfit</strong> to our training set, i.e., it has memorized the input data. So, it doesn’t generalize well to data it has not seen before. There are many ways to combat this (which are out of the scope of this workshop), but one way is to just give our model more training data. Now, we’ll train with the entire train set instead of just 500 examples:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span> <span class="o">=</span> <span class="n">preprocess</span><span class="p">(</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.1</span><span class="p">)</span>
<span class="n">linear_model</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">(</span><span class="mi">28</span><span class="o">*</span><span class="mi">28</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1000</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">linear_model</span><span class="p">(</span><span class="n">x_train</span><span class="p">))</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">categorical_crossentropy</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y_train</span><span class="p">,</span>
<span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">linear_model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 2.3025853633880615 Accuracy: 0.09871666878461838
Loss: 0.6087093949317932 Accuracy: 0.8613333106040955
Loss: 0.48937270045280457 Accuracy: 0.877216637134552
Loss: 0.44037213921546936 Accuracy: 0.885450005531311
Loss: 0.41215795278549194 Accuracy: 0.8906000256538391
Loss: 0.39325031638145447 Accuracy: 0.8945833444595337
Loss: 0.37943124771118164 Accuracy: 0.8974999785423279
Loss: 0.3687483072280884 Accuracy: 0.8997833132743835
Loss: 0.3601595163345337 Accuracy: 0.9016333222389221
Loss: 0.3530517518520355 Accuracy: 0.9029833078384399
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y_pred</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">linear_model</span><span class="p">(</span><span class="n">x_test</span><span class="p">))</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">categorical_crossentropy</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y_test</span><span class="p">,</span>
<span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 0.33095377683639526 Accuracy: 0.909600019454956
</pre>
</div>
<p>Now our model doesn’t overfit as much, but we can definitely do better. Our logistic regression model has some drawbacks:</p>
<ol>
<li>It still only models linear relationships between the explanatory and response variables. In particular, the <strong>decision boundary</strong> it models is a plane. This boundary is what determines if the model chooses one class over another.</li>
<li>It assumes the x variables are all independent, i.e., it doesn’t model any iteractions between the explanatory variables. Especially in an image like this, it’s clear there are are relationships between the variables.</li>
</ol>
<h2 id="introduction-to-artificial-neural-networks">Introduction to Artificial Neural Networks</h2>
<p>From Wikipedia:</p>
<p>“Artificial neural networks (ANN) or connectionist systems are computing systems that are inspired by, but not identical to, biological neural networks that constitute animal brains. Such systems “learn” to perform tasks by considering examples, generally without being programmed with task-specific rules. “</p>
<p>How can we make our linear or logistic regression more expressive? What if we added more weight matrices?</p>
<p>$\vec y = ((\vec xW_1 + b_1)W_2 + b_2)….W_l + \vec b_l$.</p>
<p>Well this doesn’t help, since we can define $W = W_1W_2….W_l$ (and similarly collapse $\vec b$. and it’ll just be another linear model. What if we add some nonlinear function $a$ between each linear function?</p>
<p>$\vec y = (a(a(\vec xW_1 + b_1)W_2 + b_2)….)W_l + \vec b_l$</p>
<p>This is called a <strong>fully connected neural network</strong>! $a$ is called the <strong>activation function</strong>. There are many other types of neural networks, such as Convolutional Neural Networks (which work well for images) and Recurrent Neural Networks (which work well for sequences), but they all boil down to this fundamental structure. The graph diagram you typically see for Neural Networks comes from the interpretation of each intermediate output as a neuron, and the weight matrices representing weighted edges from previous layers to later layers (we won’t worry about this for this post).</p>
<p>Common activation functions include the sigmoid function, tanh, and relu (rectified linear). This one is a common choice, so we will stick to it.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">relu</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="https://miro.medium.com/max/1283/1*DfMRHwxY1gyyDmrIAd-gjQ.png#center" alt="alt text" /></p>
<p>This function <em>is</em> non-linear, even though it is composed of linear parts.</p>
<p>We need to make a slight modification to our Linear class, then we’ll make our neural network class:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Linear</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">input_length</span><span class="p">,</span> <span class="n">output_length</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">W</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">([</span><span class="n">input_length</span><span class="p">,</span>
<span class="n">output_length</span><span class="p">]))</span>
<span class="bp">self</span><span class="p">.</span><span class="n">b</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">Variable</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">output_length</span><span class="p">))</span>
<span class="bp">self</span><span class="p">.</span><span class="n">trainable_variables</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">W</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">b</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span> <span class="c1"># assume x is a row vector
</span> <span class="k">return</span> <span class="n">x</span> <span class="o">@</span> <span class="bp">self</span><span class="p">.</span><span class="n">W</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">b</span> <span class="c1"># @ is the matrix multiplication operator
</span></code></pre></div></div>
<p>We made our initializer random. Unlike linear/logistic regression, the loss is not convex, i.e. there are multiple local minima. We initialize randomly, so we don’t bias towards any particular minimum.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">FullyConnectedNetwork</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">input_length</span><span class="p">,</span> <span class="n">output_length</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">l1</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">(</span><span class="n">input_length</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">l2</span> <span class="o">=</span> <span class="n">Linear</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="n">output_length</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">trainable_variables</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">l1</span><span class="p">.</span><span class="n">trainable_variables</span>
<span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">l2</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">l2</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">l1</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
</code></pre></div></div>
<p>This model has 1 <strong>hidden layer</strong> of size 50. Machine learning with neural networks is called <strong>deep learning</strong>, which comes from the fact that a neural network typically has several hidden layers.</p>
<p>Now, write the training loop for our neural network.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.1</span><span class="p">)</span>
<span class="n">neural_network</span> <span class="o">=</span> <span class="n">FullyConnectedNetwork</span><span class="p">(</span><span class="mi">28</span><span class="o">*</span><span class="mi">28</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1000</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">neural_network</span><span class="p">(</span><span class="n">x_train</span><span class="p">)</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">losses</span><span class="p">.</span><span class="n">categorical_crossentropy</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y_train</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">neural_network</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">neural_network</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 13.893878936767578 Accuracy: 0.10978333652019501
Loss: 7.0014495849609375 Accuracy: 0.5102999806404114
Loss: 5.423182964324951 Accuracy: 0.6128833293914795
Loss: 4.862724781036377 Accuracy: 0.6526166796684265
Loss: 4.611066818237305 Accuracy: 0.6717333197593689
Loss: 4.456557273864746 Accuracy: 0.683650016784668
Loss: 4.345137596130371 Accuracy: 0.6911166906356812
Loss: 4.257636547088623 Accuracy: 0.6973999738693237
Loss: 4.185241222381592 Accuracy: 0.701533317565918
Loss: 4.123439788818359 Accuracy: 0.7055833339691162
</pre>
</div>
<p>We wrote our neural network from scratch, but of course TensorFlow has APIs to make this much easier for you.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">tensorflow.keras.layers</span> <span class="kn">import</span> <span class="n">Dense</span>
</code></pre></div></div>
<p>TensorFlow layers function similarly to the ones we created: they have <code class="language-plaintext highlighter-rouge">trainable_variables</code> you can access, and do computation through a <code class="language-plaintext highlighter-rouge">call</code> method. They have some other nice properties as well, for example, you don’t need to specify an input shape – this will be computed upon your first use of the model.</p>
<p>You can build a model almost exactly like we did by subclassing tf.keras.Model:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Model</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">Model</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">input_length</span><span class="p">,</span> <span class="n">output_length</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span> <span class="bp">self</span><span class="p">).</span><span class="n">__init__</span><span class="p">()</span>
<span class="bp">self</span><span class="p">.</span><span class="n">layer1</span> <span class="o">=</span> <span class="n">Dense</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="n">input_shape</span><span class="o">=</span><span class="p">(</span><span class="n">input_length</span><span class="p">,),</span>
<span class="n">activation</span><span class="o">=</span><span class="s">'relu'</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">layer2</span> <span class="o">=</span> <span class="n">Dense</span><span class="p">(</span><span class="n">output_length</span><span class="p">,</span> <span class="n">input_shape</span><span class="o">=</span><span class="p">(</span><span class="n">output_length</span><span class="p">,))</span>
<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="n">output1</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">layer1</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">output2</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">layer2</span><span class="p">(</span><span class="n">output1</span><span class="p">)</span>
<span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">nn</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">output2</span><span class="p">)</span>
</code></pre></div></div>
<p>If you’re building a simple model like ours that just stacks computation, you can use the sequential API (notice we don’t specify an input shape):</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">Sequential</span><span class="p">([</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">50</span><span class="p">),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">ReLU</span><span class="p">(),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s">'softmax'</span><span class="p">)</span>
<span class="p">])</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.05</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1000</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">(</span><span class="n">x_train</span><span class="p">)</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">losses</span><span class="p">.</span><span class="n">categorical_crossentropy</span><span class="p">(</span>
<span class="n">y_true</span><span class="o">=</span><span class="n">y_train</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> '</span>
<span class="sa">f</span><span class="s">'Accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Loss: 0.2992660701274872 Accuracy: 0.9152833223342896
Loss: 0.2906898856163025 Accuracy: 0.9175333380699158
Loss: 0.2830638587474823 Accuracy: 0.919866681098938
Loss: 0.27615323662757874 Accuracy: 0.9215666651725769
Loss: 0.26982128620147705 Accuracy: 0.9236000180244446
Loss: 0.2639724612236023 Accuracy: 0.9250166416168213
Loss: 0.2585376501083374 Accuracy: 0.926716685295105
Loss: 0.25347232818603516 Accuracy: 0.9281833171844482
Loss: 0.24871543049812317 Accuracy: 0.9294000267982483
Loss: 0.24421274662017822 Accuracy: 0.9306333065032959
</pre>
</div>
<p>I encourage you to read the documentation to learn more about the layers, as there are some tricks that will make these perform slightly better than ours (e.g. initialization).</p>
<h3 id="using-tfdata">Using <code class="language-plaintext highlighter-rouge">tf.data</code></h3>
<p>Our model’s training well now, but each step is pretty slow. Our update step takes time proportional to the size of our dataset, since our loss/gradients are calculated with respect to the entire training set. Also, when working with larger datasets, this may not even be possible.</p>
<p>Instead, we can compute our loss and gradients with respect to a subset of our data called a <strong>minibatch</strong>. This is great, since our update no longer takes time proportional to our dataset size. The drawback is our update is now <strong>stochastic</strong>, since we are updating our parameters on a random subset of our data. Typically, we split our dataset into minibatches of size 32 - 256.</p>
<p>Let’s do this with TensorFlow dataset API, <code class="language-plaintext highlighter-rouge">tf.data</code>. It will be much more performant than raw tensors for minibatch gradient descent.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">train</span><span class="p">,</span> <span class="n">test</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">datasets</span><span class="p">.</span><span class="n">mnist</span><span class="p">.</span><span class="n">load_data</span><span class="p">()</span>
</code></pre></div></div>
<p>Given numpy arrays as input, we can simply turn them into datasets with <code class="language-plaintext highlighter-rouge">from_tensor_slices</code>. There’s the <code class="language-plaintext highlighter-rouge">tensorflow_datasets</code> library that has many datasets built in</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">train_dataset</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">Dataset</span><span class="p">.</span><span class="n">from_tensor_slices</span><span class="p">(</span><span class="n">train</span><span class="p">)</span>
<span class="n">test_dataset</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">Dataset</span><span class="p">.</span><span class="n">from_tensor_slices</span><span class="p">(</span><span class="n">test</span><span class="p">)</span>
</code></pre></div></div>
<p>We need to do some similar preprocessing of the data. Notice we aren’t one_hot encoding y. TensorFlow has a loss function called <code class="language-plaintext highlighter-rouge">sparse_categorical_crossentropy</code>, which is the same as <code class="language-plaintext highlighter-rouge">categorical_crossentropy</code> except it allows the <code class="language-plaintext highlighter-rouge">y_true</code> to be an index instead of a one hot tensor (which is faster and more memory efficient). We need to change our accuracy function to reflect that.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">preprocess_tfdata</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="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">28</span><span class="o">*</span><span class="mi">28</span><span class="p">))</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span> <span class="o">/</span> <span class="mf">255.0</span>
<span class="k">return</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">sparse_accuracy</span><span class="p">(</span><span class="n">y_true</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">):</span>
<span class="n">equal_preds</span> <span class="o">=</span> <span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">argmax</span><span class="p">(</span><span class="n">y_pred</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="o">==</span> <span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">y_true</span><span class="p">,</span> <span class="n">tf</span><span class="p">.</span><span class="n">int64</span><span class="p">))</span>
<span class="k">return</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">tf</span><span class="p">.</span><span class="n">cast</span><span class="p">(</span><span class="n">equal_preds</span><span class="p">,</span> <span class="n">tf</span><span class="p">.</span><span class="n">float32</span><span class="p">))</span>
</code></pre></div></div>
<p>We apply this preprocessing to our dataset using <code class="language-plaintext highlighter-rouge">map</code>. Then, we shuffle our data. Since we are batching our data, we don’t want to use the same minibatches for every pass of the dataset, because that would introduce bias. Then, we batch our data into batches of size 256. Finally, we prefetch, which means the next batch will be loaded and ready to go before the previous one finishes. There are tons of optimizations you can do to get more performance, which you can read about <a href="https://www.tensorflow.org/guide/data_performance">here</a>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">train_dataset</span> <span class="o">=</span> <span class="n">train_dataset</span><span class="p">.</span><span class="nb">map</span><span class="p">(</span><span class="n">preprocess_tfdata</span><span class="p">).</span><span class="n">shuffle</span><span class="p">(</span>
<span class="n">buffer_size</span><span class="o">=</span><span class="mi">5000</span><span class="p">)</span>
<span class="n">train_dataset</span> <span class="o">=</span> <span class="n">train_dataset</span><span class="p">.</span><span class="n">batch</span><span class="p">(</span><span class="mi">256</span><span class="p">).</span><span class="n">prefetch</span><span class="p">(</span>
<span class="n">buffer_size</span><span class="o">=</span><span class="n">tf</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">experimental</span><span class="p">.</span><span class="n">AUTOTUNE</span><span class="p">)</span>
<span class="n">test_dataset</span> <span class="o">=</span> <span class="n">test_dataset</span><span class="p">.</span><span class="nb">map</span><span class="p">(</span><span class="n">preprocess_tfdata</span><span class="p">).</span><span class="n">batch</span><span class="p">(</span><span class="mi">256</span><span class="p">)</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">Sequential</span><span class="p">([</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">50</span><span class="p">),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">ReLU</span><span class="p">(),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s">'softmax'</span><span class="p">)</span>
<span class="p">])</span>
</code></pre></div></div>
<p>Now we can train. This time, our loop looks a bit different. We call every pass of our dataset an <strong>epoch</strong>. Then, each minibatch process is called a <strong>training step</strong>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.05</span><span class="p">)</span>
<span class="n">loss_fn</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">losses</span><span class="p">.</span><span class="n">SparseCategoricalCrossentropy</span><span class="p">(</span>
<span class="n">from_logits</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="c1"># since we don't softmax our output
</span>
<span class="k">for</span> <span class="n">epoch</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span>
<span class="k">for</span> <span class="n">step</span><span class="p">,</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="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">train_dataset</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">loss_fn</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span>
<span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Epoch </span><span class="si">{</span><span class="n">epoch</span><span class="si">}</span><span class="s"> Step </span><span class="si">{</span><span class="n">step</span><span class="si">}</span><span class="s"> Loss: </span><span class="si">{</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">()</span><span class="si">}</span><span class="s"> '</span>
<span class="sa">f</span><span class="s">'Accuracy: </span><span class="si">{</span><span class="n">sparse_accuracy</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">)</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Epoch 0 Step 0 Loss: 2.420623302459717 Accuracy: 0.0703125
Epoch 0 Step 100 Loss: 0.6510080099105835 Accuracy: 0.8515625
Epoch 0 Step 200 Loss: 0.5177682638168335 Accuracy: 0.86328125
Epoch 1 Step 0 Loss: 0.415408730506897 Accuracy: 0.87890625
Epoch 1 Step 100 Loss: 0.4126032888889313 Accuracy: 0.8984375
Epoch 1 Step 200 Loss: 0.365292489528656 Accuracy: 0.89453125
</pre>
</div>
<h3 id="metrics">Metrics</h3>
<p>Now our model’s training really quickly. But, we’re reporting statistics on individual minibatches. Ideally, we can report statistics on the entire training set at the end of each epoch. Or, report statistics on the data we’ve seen since the previous report. Let’s implement this.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Mean</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">vals</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">add_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">vals</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">sum</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">vals</span><span class="p">)</span><span class="o">/</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">vals</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">reset_states</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">vals</span> <span class="o">=</span> <span class="p">[]</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">Sequential</span><span class="p">([</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">50</span><span class="p">),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">ReLU</span><span class="p">(),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s">'softmax'</span><span class="p">)</span>
<span class="p">])</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.05</span><span class="p">)</span>
<span class="n">loss_fn</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">losses</span><span class="p">.</span><span class="n">SparseCategoricalCrossentropy</span><span class="p">(</span><span class="n">from_logits</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">loss_mean</span> <span class="o">=</span> <span class="n">Mean</span><span class="p">()</span>
<span class="n">accuracy_mean</span> <span class="o">=</span> <span class="n">Mean</span><span class="p">()</span>
<span class="k">for</span> <span class="n">epoch</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span>
<span class="k">for</span> <span class="n">step</span><span class="p">,</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="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">train_dataset</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">loss_fn</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="n">loss_mean</span><span class="p">.</span><span class="n">add_value</span><span class="p">(</span><span class="n">loss</span><span class="p">.</span><span class="n">numpy</span><span class="p">())</span>
<span class="n">accuracy_mean</span><span class="p">.</span><span class="n">add_value</span><span class="p">(</span><span class="n">sparse_accuracy</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="p">))</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Epoch </span><span class="si">{</span><span class="n">epoch</span><span class="si">}</span><span class="s"> Step </span><span class="si">{</span><span class="n">step</span><span class="si">}</span><span class="s"> Loss: </span><span class="si">{</span><span class="n">loss_mean</span><span class="p">.</span><span class="n">result</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy_mean</span><span class="p">.</span><span class="n">result</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
<span class="n">loss_mean</span><span class="p">.</span><span class="n">reset_states</span><span class="p">()</span>
<span class="n">accuracy_mean</span><span class="p">.</span><span class="n">reset_states</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Epoch 0 Step 0 Loss: 2.346635580062866 Accuracy: 0.15234375
Epoch 0 Step 100 Loss: 1.2027271282672882 Accuracy: 0.6998828053474426
Epoch 0 Step 200 Loss: 0.5806717258691788 Accuracy: 0.8575390577316284
Epoch 1 Step 0 Loss: 0.43301645602498734 Accuracy: 0.8878348469734192
Epoch 1 Step 100 Loss: 0.42787124931812287 Accuracy: 0.8848046660423279
Epoch 1 Step 200 Loss: 0.4001629453897476 Accuracy: 0.8896093964576721
</pre>
</div>
<p>Of course, TensorFlow already has a way to do this. One key difference is <code class="language-plaintext highlighter-rouge">tf.keras.metrics</code> accumulate a sum and a count instead of keeping a list of all past values (more details <a href="https://www.tensorflow.org/api_docs/python/tf/keras/metrics">here</a>).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">optimizers</span><span class="p">.</span><span class="n">SGD</span><span class="p">(</span><span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.05</span><span class="p">)</span>
<span class="n">loss_fn</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">losses</span><span class="p">.</span><span class="n">SparseCategoricalCrossentropy</span><span class="p">(</span><span class="n">from_logits</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">loss_metric</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">metrics</span><span class="p">.</span><span class="n">Mean</span><span class="p">()</span>
<span class="n">accuracy_metric</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">metrics</span><span class="p">.</span><span class="n">SparseCategoricalAccuracy</span><span class="p">()</span>
<span class="k">for</span> <span class="n">epoch</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span>
<span class="k">for</span> <span class="n">step</span><span class="p">,</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="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">train_dataset</span><span class="p">):</span>
<span class="k">with</span> <span class="n">tf</span><span class="p">.</span><span class="n">GradientTape</span><span class="p">()</span> <span class="k">as</span> <span class="n">tape</span><span class="p">:</span>
<span class="n">y_pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">loss_per_example</span> <span class="o">=</span> <span class="n">loss_fn</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">reduce_mean</span><span class="p">(</span><span class="n">loss_per_example</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="n">tape</span><span class="p">.</span><span class="n">gradient</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">)</span>
<span class="n">optimizer</span><span class="p">.</span><span class="n">apply_gradients</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">gradient</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="n">trainable_variables</span><span class="p">))</span>
<span class="n">loss_metric</span><span class="p">(</span><span class="n">loss</span><span class="p">)</span>
<span class="n">accuracy_metric</span><span class="p">(</span><span class="n">y_true</span><span class="o">=</span><span class="n">y</span><span class="p">,</span> <span class="n">y_pred</span><span class="o">=</span><span class="n">y_pred</span><span class="p">)</span>
<span class="k">if</span> <span class="n">step</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Epoch </span><span class="si">{</span><span class="n">epoch</span><span class="si">}</span><span class="s"> Step </span><span class="si">{</span><span class="n">step</span><span class="si">}</span><span class="s"> Loss: </span><span class="si">{</span><span class="n">loss_metric</span><span class="p">.</span><span class="n">result</span><span class="p">()</span><span class="si">}</span><span class="s"> Accuracy: </span><span class="si">{</span><span class="n">accuracy_metric</span><span class="p">.</span><span class="n">result</span><span class="p">()</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
<span class="n">loss_metric</span><span class="p">.</span><span class="n">reset_states</span><span class="p">()</span>
<span class="n">accuracy_metric</span><span class="p">.</span><span class="n">reset_states</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Epoch 0 Step 0 Loss: 0.30616647005081177 Accuracy: 0.9140625
Epoch 0 Step 100 Loss: 0.3538685739040375 Accuracy: 0.9021875262260437
Epoch 0 Step 200 Loss: 0.34719112515449524 Accuracy: 0.9018359184265137
Epoch 1 Step 0 Loss: 0.28928661346435547 Accuracy: 0.9163636565208435
Epoch 1 Step 100 Loss: 0.3155575692653656 Accuracy: 0.9126172065734863
Epoch 1 Step 200 Loss: 0.32115286588668823 Accuracy: 0.908007800579071
</pre>
</div>
<h2 id="we-did-a-bunch-of-heavy-lifting-we-dont-have-to">We did a bunch of heavy lifting. We don’t have to.</h2>
<p>Keras has really high level APIs that take care of all the work we did for us.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">),</span> <span class="p">(</span><span class="n">x_test</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">datasets</span><span class="p">.</span><span class="n">mnist</span><span class="p">.</span><span class="n">load_data</span><span class="p">()</span>
<span class="n">x_train</span> <span class="o">=</span> <span class="n">x_train</span><span class="o">/</span><span class="mf">255.0</span>
<span class="n">x_test</span> <span class="o">=</span> <span class="n">x_test</span><span class="o">/</span><span class="mf">255.0</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">Sequential</span><span class="p">([</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Flatten</span><span class="p">(),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">50</span><span class="p">),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">ReLU</span><span class="p">(),</span>
<span class="n">tf</span><span class="p">.</span><span class="n">keras</span><span class="p">.</span><span class="n">layers</span><span class="p">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s">'softmax'</span><span class="p">)</span>
<span class="p">])</span>
<span class="n">model</span><span class="p">.</span><span class="nb">compile</span><span class="p">(</span><span class="n">optimizer</span><span class="o">=</span><span class="s">'sgd'</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s">'sparse_categorical_crossentropy'</span><span class="p">,</span>
<span class="n">metrics</span><span class="o">=</span><span class="p">[</span><span class="s">'accuracy'</span><span class="p">])</span>
<span class="n">history</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="n">y_train</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span> <span class="n">epochs</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span>
<span class="n">validation_data</span><span class="o">=</span><span class="p">(</span><span class="n">x_test</span><span class="p">,</span> <span class="n">y_test</span><span class="p">))</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Train on 60000 samples, validate on 10000 samples
Epoch 1/10
60000/60000 [==============================] - 2s 28us/sample - loss: 1.6077 - accuracy: 0.5817 - val_loss: 1.0738 - val_accuracy: 0.7891
Epoch 2/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.8704 - accuracy: 0.8139 - val_loss: 0.6882 - val_accuracy: 0.8476
Epoch 3/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.6321 - accuracy: 0.8508 - val_loss: 0.5457 - val_accuracy: 0.8697
Epoch 4/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.5306 - accuracy: 0.8660 - val_loss: 0.4755 - val_accuracy: 0.8798
Epoch 5/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.4746 - accuracy: 0.8761 - val_loss: 0.4336 - val_accuracy: 0.8860
Epoch 6/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.4389 - accuracy: 0.8819 - val_loss: 0.4050 - val_accuracy: 0.8900
Epoch 7/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.4140 - accuracy: 0.8877 - val_loss: 0.3852 - val_accuracy: 0.8946
Epoch 8/10
60000/60000 [==============================] - 1s 20us/sample - loss: 0.3954 - accuracy: 0.8910 - val_loss: 0.3695 - val_accuracy: 0.8980
Epoch 9/10
60000/60000 [==============================] - 1s 19us/sample - loss: 0.3807 - accuracy: 0.8942 - val_loss: 0.3573 - val_accuracy: 0.9001
Epoch 10/10
60000/60000 [==============================] - 1s 20us/sample - loss: 0.3686 - accuracy: 0.8968 - val_loss: 0.3470 - val_accuracy: 0.9029
</pre>
</div>
<p>These APIs are highly performant and robust, so you don’t have to worry about messing things up. Use them whenever you can!</p>
<h2 id="conclusion">Conclusion</h2>
<p>We covered the fundamentals of neural networks and of TensorFlow 2. Note we emphasized the fundamentals and implementing them from scratch. You should look at other sources online for more idiomatic code, such as the <a href="https://keras.io/examples/">keras examples page</a>.</p>
<p>Here are some things I’d recommend checking out next for Neural Networks:</p>
<ul>
<li>Backpropagation (how are the gradients computed? spoiler: it’s chain rule!)</li>
<li>Convolutional and Recurrent Neural Networks</li>
<li>Regularization (my model’s still overfitting! how do I fix that?)</li>
</ul>
<p>Here are some things I’d recommend checking out for TensorFlow 2:</p>
<ul>
<li>The various layers, metrics, losses, optimizers, and activation functions offered.</li>
<li>Functional API for building models</li>
<li>Using <code class="language-plaintext highlighter-rouge">@tf.function</code> to speed up your code</li>
<li>Distributed Training with <code class="language-plaintext highlighter-rouge">tf.distribute</code></li>
</ul>Nicholas Vadivelunicholas.vadivelu@gmail.comIn this workshop, we will learn about Neural Networks and how to build them in TensorFlow 2.Introduction to Data Cleaning with Pandas2019-09-27T00:00:00+00:002019-09-27T00:00:00+00:00https://nicholasvadivelu.com/2019/09/27/intro-to-pandas<p>Through this workshop, you will learn how to use Pandas to explore and “wrangle” datasets. Topics will include an introduction to Jupyter Notebooks/Colab, data cleaning with pandas, feature engineering with pandas, basic visualization and more. This workshop will focus on actual coding.</p>
<p>This article provides a summary of the main workshop, which you can watch <a href="https://youtu.be/mesgiVk8G6s">here</a>. <a href="https://colab.research.google.com/github/n2cholas/dsc-workshops/blob/master/Introduction_to_Data_Cleaning_with_Pandas.ipynb">Here</a> is a colab link to run all the code.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
</code></pre></div></div>
<h2 id="jupyter-tips">Jupyter Tips</h2>
<p>Before starting with pandas, let’s look at some useful features Jupyter has that will help us along the way.</p>
<p>Typing a function then pressing tab gives you a list of arguments you can enter. Pressing shift-tab gives you the function signature. Also:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">?</span><span class="n">pd</span><span class="p">.</span><span class="n">Series</span> <span class="c1"># using one question mark gives you the function/class signature with the description
</span><span class="err">??</span><span class="n">pd</span><span class="p">.</span><span class="n">Series</span> <span class="c1"># two question marks gives you the actual code for that function
</span></code></pre></div></div>
<p>Timing your pandas code is a very helpful learning tool, so you can figure out the most efficient way to do things. You can time code as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">timeit</span> <span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">500</span><span class="p">)]</span> <span class="c1"># in line mode
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
100000 loops, best of 3: 14 µs per loop
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">timeit</span> <span class="c1"># time an entire cell
</span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="bp">None</span><span class="p">;</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
The slowest run took 5.44 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 300 ns per loop
</pre>
</div>
<p>Commands prefaced by “%” or “%%” are called magic commands. You can read about more <a href="https://ipython.readthedocs.io/en/stable/interactive/magics.html">here</a>.</p>
<h2 id="what-is-pandas">What is Pandas?</h2>
<p>Pandas is a Python library for manipulating data and performing analysis. It has too many fefatures to cover in one introductory workshop, but you will find the documentation complete and clear: https://pandas.pydata.org/pandas-docs/stable/. For many tasks, there is likely a Pandas function to make your life easier, so Google away!</p>
<p>The most basic unit in Pandas is called a Series:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">s</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">Series</span><span class="p">([</span><span class="s">'a'</span><span class="p">,</span> <span class="s">'b'</span><span class="p">,</span> <span class="s">'c'</span><span class="p">,</span> <span class="s">'d'</span><span class="p">,</span> <span class="s">'e'</span><span class="p">,</span> <span class="s">'f'</span><span class="p">,</span> <span class="s">'g'</span><span class="p">])</span>
<span class="n">s</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
0 a
1 b
2 c
3 d
4 e
5 f
6 g
dtype: object
</pre>
</div>
<p>A series is simply a 1D numpy array with some more functionality built on top. Above, on the left you see an index and on the right are the actual values. The “dtype” is the datatype, which can be anything from objects (usually strings), integers, floats, categorical variables, datetimes, etc. Series are much faster than built in python lists because the numpy backend is written in C.</p>
<p>You can index into a series exactly the same as you would a numpy array:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># returns the 2nd element (0 indexed)
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
'b'
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span> <span class="c1"># returns a series from indices 1 to 3 (exclusive)
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
1 b
2 c
dtype: object
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">::</span><span class="mi">2</span><span class="p">]</span> <span class="c1"># returns series from indices 1 to the end, counting by 2s (i.e. 1, 3, 5)
</span></code></pre></div></div>
<div class="output_block">
<pre class="output">
1 b
3 d
5 f
dtype: object
</pre>
</div>
<p>You also retain the same broadcasting numpy arrays do. For example</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">s2</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">Series</span><span class="p">([</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">50</span><span class="p">)])</span>
<span class="n">s2</span> <span class="o">=</span> <span class="n">s2</span><span class="o">/</span><span class="mi">50</span> <span class="o">+</span> <span class="mi">1</span>
</code></pre></div></div>
<p>You can also sample a random element from a series:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">s2</span><span class="p">.</span><span class="n">sample</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
2 1.04
dtype: float64
</pre>
</div>
<p>Next, let’s import some data and jump into Dataframes. Dataframes are tables of data, where each column has a name and is a series of some type. Each column can have a different type.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'https://raw.githubusercontent.com/n2cholas/pokemon-analysis/master/pokemon-data.csv'</span><span class="p">,</span> <span class="n">delimiter</span><span class="o">=</span><span class="s">';'</span><span class="p">)</span>
<span class="n">mdf</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'https://raw.githubusercontent.com/n2cholas/pokemon-analysis/master/move-data.csv'</span><span class="p">,</span> <span class="n">delimiter</span><span class="o">=</span><span class="s">';'</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">'Number of pokemon: '</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">df</span><span class="p">))</span>
<span class="n">df</span><span class="p">.</span><span class="n">sample</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
Number of pokemon: 918
</pre>
</div>
<div style="overflow-x:auto;">
<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>Name</th>
<th>Types</th>
<th>Abilities</th>
<th>Tier</th>
<th>HP</th>
<th>Attack</th>
<th>Defense</th>
<th>Special Attack</th>
<th>Special Defense</th>
<th>Speed</th>
<th>Next Evolution(s)</th>
<th>Moves</th>
</tr>
</thead>
<tbody>
<tr>
<th>552</th>
<td>Octillery</td>
<td>['Water']</td>
<td>['Moody', 'Sniper', 'Suction Cups']</td>
<td>PU</td>
<td>75</td>
<td>105</td>
<td>75</td>
<td>105</td>
<td>75</td>
<td>45</td>
<td>[]</td>
<td>['Gunk Shot', 'Rock Blast', 'Water Gun', 'Cons...</td>
</tr>
</tbody>
</table>
</div>
<p>We can also take samples of different sizes, or look at the top of the dataset, or the bottom:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">head</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Index</th>
<th>Name</th>
<th>Type</th>
<th>Category</th>
<th>Contest</th>
<th>PP</th>
<th>Power</th>
<th>Accuracy</th>
<th>Generation</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1</td>
<td>Pound</td>
<td>Normal</td>
<td>Physical</td>
<td>Tough</td>
<td>35</td>
<td>40</td>
<td>100</td>
<td>1</td>
</tr>
<tr>
<th>1</th>
<td>2</td>
<td>Karate Chop</td>
<td>Fighting</td>
<td>Physical</td>
<td>Tough</td>
<td>25</td>
<td>50</td>
<td>100</td>
<td>1</td>
</tr>
<tr>
<th>2</th>
<td>3</td>
<td>Double Slap</td>
<td>Normal</td>
<td>Physical</td>
<td>Cute</td>
<td>10</td>
<td>15</td>
<td>85</td>
<td>1</td>
</tr>
</tbody>
</table>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">sample</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Index</th>
<th>Name</th>
<th>Type</th>
<th>Category</th>
<th>Contest</th>
<th>PP</th>
<th>Power</th>
<th>Accuracy</th>
<th>Generation</th>
</tr>
</thead>
<tbody>
<tr>
<th>551</th>
<td>552</td>
<td>Fiery Dance</td>
<td>Fire</td>
<td>Special</td>
<td>Beautiful</td>
<td>10</td>
<td>80</td>
<td>100</td>
<td>5</td>
</tr>
<tr>
<th>84</th>
<td>85</td>
<td>Thunderbolt</td>
<td>Electric</td>
<td>Special</td>
<td>Cool</td>
<td>15</td>
<td>90</td>
<td>100</td>
<td>1</td>
</tr>
</tbody>
</table>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">tail</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Index</th>
<th>Name</th>
<th>Type</th>
<th>Category</th>
<th>Contest</th>
<th>PP</th>
<th>Power</th>
<th>Accuracy</th>
<th>Generation</th>
</tr>
</thead>
<tbody>
<tr>
<th>723</th>
<td>724</td>
<td>Searing Sunraze Smash</td>
<td>Steel</td>
<td>Special</td>
<td>???</td>
<td>1</td>
<td>200</td>
<td>None</td>
<td>7</td>
</tr>
<tr>
<th>724</th>
<td>725</td>
<td>Menacing Moonraze Maelstrom</td>
<td>Ghost</td>
<td>Special</td>
<td>???</td>
<td>1</td>
<td>200</td>
<td>None</td>
<td>7</td>
</tr>
<tr>
<th>725</th>
<td>726</td>
<td>Let's Snuggle Forever</td>
<td>Fairy</td>
<td>Physical</td>
<td>???</td>
<td>1</td>
<td>190</td>
<td>None</td>
<td>7</td>
</tr>
<tr>
<th>726</th>
<td>727</td>
<td>Splintered Stormshards</td>
<td>Rock</td>
<td>Physical</td>
<td>???</td>
<td>1</td>
<td>190</td>
<td>None</td>
<td>7</td>
</tr>
<tr>
<th>727</th>
<td>728</td>
<td>Clangorous Soulblaze</td>
<td>Dragon</td>
<td>Special</td>
<td>???</td>
<td>1</td>
<td>185</td>
<td>None</td>
<td>7</td>
</tr>
</tbody>
</table>
</div>
<h2 id="initial-processing">Initial Processing</h2>
<p>We don’t need the index column because Pandas gives us a default index, so let’s drop that column.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="s">'Index'</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># mdf = mdf.drop(columns='Index') # alternative
</span></code></pre></div></div>
<p>Many pandas functions return a changed version of the dataframe instead of modifying the dataframe itself. We can use inplace=True to do it inplace (which is more efficient). Sometimes, when using multiple commands consecutively, it’ easier to chain the commands instead of doing it inplace (as you’ll see).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="s">'name'</span><span class="p">,</span> <span class="s">'type'</span><span class="p">,</span> <span class="s">'category'</span><span class="p">,</span> <span class="s">'contest'</span><span class="p">,</span> <span class="s">'pp'</span><span class="p">,</span> <span class="s">'power'</span><span class="p">,</span> <span class="s">'accuracy'</span><span class="p">,</span> <span class="s">'generation'</span><span class="p">]</span> <span class="c1">#set column names
</span>
<span class="n">mdf</span><span class="p">.</span><span class="n">dtypes</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
name object
type object
category object
contest object
pp int64
power object
accuracy object
generation int64
dtype: object
</pre>
</div>
<p>Pandas usually does a good job of detecting the datatypes of various columns. We know that power and accuracy should be numbers, but pandas is making them objects (strings). This usually indicates null values. Let’s check.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">[</span><span class="s">'accuracy'</span><span class="p">].</span><span class="n">value_counts</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 320
None 280
90 46
95 29
85 26
75 10
80 7
70 4
55 3
50 3
Name: accuracy, dtype: int64
</pre>
</div>
<p>Just as we suspected, there is the string “None” for non-numeric values. Let’s fix this.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">[</span><span class="s">'accuracy'</span><span class="p">].</span><span class="n">replace</span><span class="p">(</span><span class="s">'None'</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="c1"># notice mdf.accuracy.replace(..., inplace=True) wouldn't work
</span><span class="n">mdf</span><span class="p">[</span><span class="s">'accuracy'</span><span class="p">]</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">to_numeric</span><span class="p">(</span><span class="n">mdf</span><span class="p">[</span><span class="s">'accuracy'</span><span class="p">])</span>
</code></pre></div></div>
<p>Below, we get a boolean series indicating whether the column is ‘None’ or not. We can use this boolean series to index into the dataframe.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">power</span> <span class="o">==</span> <span class="s">'None'</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
0 False
1 False
2 False
3 False
4 False
5 False
6 False
7 False
8 False
9 False
10 False
11 True
12 False
13 True
14 False
15 False
16 False
17 True
18 False
19 False
20 False
21 False
22 False
23 False
24 False
25 False
26 False
27 True
28 False
29 False
...
698 False
699 False
700 False
701 True
702 False
703 False
704 False
705 False
706 False
707 False
708 False
709 False
710 False
711 False
712 False
713 False
714 True
715 False
716 True
717 False
718 False
719 False
720 False
721 False
722 False
723 False
724 False
725 False
726 False
727 False
Name: power, Length: 728, dtype: bool
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">[</span><span class="n">mdf</span><span class="p">.</span><span class="n">power</span> <span class="o">==</span> <span class="s">'None'</span><span class="p">].</span><span class="n">head</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>name</th>
<th>type</th>
<th>category</th>
<th>contest</th>
<th>pp</th>
<th>power</th>
<th>accuracy</th>
<th>generation</th>
</tr>
</thead>
<tbody>
<tr>
<th>11</th>
<td>Guillotine</td>
<td>Normal</td>
<td>Physical</td>
<td>Cool</td>
<td>5</td>
<td>None</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<th>13</th>
<td>Swords Dance</td>
<td>Normal</td>
<td>Status</td>
<td>Beautiful</td>
<td>20</td>
<td>None</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<th>17</th>
<td>Whirlwind</td>
<td>Normal</td>
<td>Status</td>
<td>Clever</td>
<td>20</td>
<td>None</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<th>27</th>
<td>Sand Attack</td>
<td>Ground</td>
<td>Status</td>
<td>Cute</td>
<td>15</td>
<td>None</td>
<td>100</td>
<td>1</td>
</tr>
<tr>
<th>31</th>
<td>Horn Drill</td>
<td>Normal</td>
<td>Physical</td>
<td>Cool</td>
<td>5</td>
<td>None</td>
<td>0</td>
<td>1</td>
</tr>
</tbody>
</table>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">mdf</span><span class="p">.</span><span class="n">power</span> <span class="o">==</span> <span class="s">'None'</span><span class="p">,</span> <span class="s">'power'</span><span class="p">].</span><span class="n">head</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
11 None
13 None
17 None
27 None
31 None
Name: power, dtype: object
</pre>
</div>
<p>.loc is a common way to index into a Dataframe. The first argument is the index (or list of indices), or a boolean array that acts as a mask. iloc can be used similarly, except the first number is the actual numeric index (notice that a Dataframe index can be non-numeric).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">mdf</span><span class="p">.</span><span class="n">power</span> <span class="o">==</span> <span class="s">'None'</span><span class="p">,</span> <span class="s">'power'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">mdf</span><span class="p">[</span><span class="s">'power'</span><span class="p">]</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">to_numeric</span><span class="p">(</span><span class="n">mdf</span><span class="p">[</span><span class="s">'power'</span><span class="p">])</span>
<span class="n">mdf</span><span class="p">.</span><span class="n">dtypes</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
name object
type object
category object
contest object
pp int64
power int64
accuracy int64
generation int64
dtype: object
</pre>
</div>
<p>We were able to convert them with no issues. Notice the two ways to access columns. The only difference between the two is that the dictionary-style access allows you to modify the column, and allows you to create new columns. You can only use the .column method for existing columns, and it returns a copy (so the modifications won’t affect the original Dataframe). Also, notice you can’t access columns with spaces in their names with the .column notation.</p>
<p>Although the dictionary-style access is more consistent, I like to use the .column access whenever I can because it is faster to type.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="s">'name'</span><span class="p">,</span> <span class="s">'types'</span><span class="p">,</span> <span class="s">'abilities'</span><span class="p">,</span> <span class="s">'tier'</span><span class="p">,</span> <span class="s">'hp'</span><span class="p">,</span> <span class="s">'atk'</span><span class="p">,</span> <span class="s">'def'</span><span class="p">,</span> <span class="s">'spa'</span><span class="p">,</span> <span class="s">'spd'</span><span class="p">,</span> <span class="s">'spe'</span><span class="p">,</span> <span class="s">'next_evos'</span><span class="p">,</span><span class="s">'moves'</span><span class="p">]</span>
<span class="n">df</span><span class="p">.</span><span class="n">dtypes</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
name object
types object
abilities object
tier object
hp int64
atk int64
def int64
spa int64
spd int64
spe int64
next_evos object
moves object
dtype: object
</pre>
</div>
<p>We saw above that the next_evos, moves, abilities, and types columns should be lists, so we can do that.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">temp_df</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">copy</span><span class="p">()</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">timeit</span>
<span class="k">for</span> <span class="n">ind</span><span class="p">,</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">temp_df</span><span class="p">.</span><span class="n">iterrows</span><span class="p">():</span>
<span class="n">df</span><span class="p">.</span><span class="n">at</span><span class="p">[</span><span class="n">ind</span><span class="p">,</span> <span class="s">'next_evos'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s">'next_evos'</span><span class="p">])</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
10 loops, best of 3: 108 ms per loop
</pre>
</div>
<p>A few notes. This seems like the most obvious way to achieve what we want. Look through the rows using iterrows, use python’s “eval” to turn a string-list into an actual list, then assign it to the dataframe at that index. Notice that we use “at”, which is the same as “loc” except it can only access one value at a time.</p>
<p>This turns out to be the worst way to do this. In pandas, we can almost always avoid explicitly looping through our data.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">timeit</span>
<span class="n">df</span><span class="p">[</span><span class="s">'types'</span><span class="p">]</span> <span class="o">=</span> <span class="n">temp_df</span><span class="p">.</span><span class="nb">apply</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="nb">eval</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">types</span><span class="p">),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
10 loops, best of 3: 22.4 ms per loop
</pre>
</div>
<p>This is much better. The apply function applies a function you give it to all the rows or columns in the dataframe. The axis argument specifies whether it’s rows or columns. We can make this a bit cleaner.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">timeit</span>
<span class="n">df</span><span class="p">[</span><span class="s">'abilities'</span><span class="p">]</span> <span class="o">=</span> <span class="n">temp_df</span><span class="p">.</span><span class="n">abilities</span><span class="p">.</span><span class="nb">map</span><span class="p">(</span><span class="nb">eval</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100 loops, best of 3: 6.12 ms per loop
</pre>
</div>
<p>This is very clean. While apply works on a dataframe, map works on a single series. Also, since the value is always just applied to the one column, we can just pass the eval function instead of using a lambda. Our next improvement won’t be faster, but it’ll be nicer</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span>
<span class="n">tqdm</span><span class="p">.</span><span class="n">pandas</span><span class="p">()</span>
<span class="n">df</span><span class="p">[</span><span class="s">'moves'</span><span class="p">]</span> <span class="o">=</span> <span class="n">temp_df</span><span class="p">.</span><span class="n">moves</span><span class="p">.</span><span class="n">progress_map</span><span class="p">(</span><span class="nb">eval</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100%|██████████| 918/918 [00:00<00:00, 8454.77it/s]
</pre>
</div>
<p>tqdm is a library that provides progress bars for loops, but it can be easily used with pandas to provide a progress bar for your maps and applies. Very useful for doing complex processing on large datasets.</p>
<p>Next, notice that our dataframe has one row per pokemon. It would be nice to index into by the pokemon name rather than a number. If we are going to access rows by pokemon name often, this will give us a speed advantage, since the items in the index are supported in the backend by a hashtable.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">set_index</span><span class="p">(</span><span class="s">'name'</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'Pikachu'</span><span class="p">]</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
types [Electric]
abilities [Lightning Rod, Static]
tier NaN
hp 35
atk 55
def 40
spa 50
spd 50
spe 90
next_evos [Raichu, Raichu-Alola]
moves [Tail Whip, Thunder Shock, Growl, Play Nice, T...
Name: Pikachu, dtype: object
</pre>
</div>
<p>We can also reset_index, which can be useful sometimes. Now that we’ve done some processing, we can produce a summary of the numeric columns:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">describe</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>hp</th>
<th>atk</th>
<th>def</th>
<th>spa</th>
<th>spd</th>
<th>spe</th>
</tr>
</thead>
<tbody>
<tr>
<th>count</th>
<td>918.000000</td>
<td>918.000000</td>
<td>918.000000</td>
<td>918.000000</td>
<td>918.000000</td>
<td>918.000000</td>
</tr>
<tr>
<th>mean</th>
<td>69.558824</td>
<td>80.143791</td>
<td>74.535948</td>
<td>73.297386</td>
<td>72.384532</td>
<td>68.544662</td>
</tr>
<tr>
<th>std</th>
<td>26.066527</td>
<td>32.697233</td>
<td>31.225467</td>
<td>33.298652</td>
<td>27.889548</td>
<td>29.472307</td>
</tr>
<tr>
<th>min</th>
<td>1.000000</td>
<td>5.000000</td>
<td>5.000000</td>
<td>10.000000</td>
<td>20.000000</td>
<td>5.000000</td>
</tr>
<tr>
<th>25%</th>
<td>50.000000</td>
<td>55.000000</td>
<td>50.000000</td>
<td>50.000000</td>
<td>50.000000</td>
<td>45.000000</td>
</tr>
<tr>
<th>50%</th>
<td>66.500000</td>
<td>75.000000</td>
<td>70.000000</td>
<td>65.000000</td>
<td>70.000000</td>
<td>65.000000</td>
</tr>
<tr>
<th>75%</th>
<td>80.000000</td>
<td>100.000000</td>
<td>90.000000</td>
<td>95.000000</td>
<td>90.000000</td>
<td>90.000000</td>
</tr>
<tr>
<th>max</th>
<td>255.000000</td>
<td>190.000000</td>
<td>230.000000</td>
<td>194.000000</td>
<td>230.000000</td>
<td>180.000000</td>
</tr>
</tbody>
</table>
</div>
<h2 id="data-correction">Data Correction</h2>
<p>Typically, you will find oddities in your data during analysis. Perhaps you visualize a column, and the numbers look off, so you look into the actual data and notice some issues. For the purpose of this workshop, we’ll skip the visualization and just correct the data</p>
<p>First, some pokemon have moves duplicated. Let’s fix this by making the move-lists into movesets</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">[</span><span class="s">'moves'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">moves</span><span class="p">.</span><span class="n">progress_map</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100%|██████████| 918/918 [00:00<00:00, 68711.23it/s]
</pre>
</div>
<p>Next, I noticed a weird quirk with the strings for the moves. This will cause some trouble if we want to relate the mdf and df tables, so let’s fix it.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">moves</span> <span class="o">=</span> <span class="p">{</span><span class="n">move</span> <span class="k">for</span> <span class="n">move_set</span> <span class="ow">in</span> <span class="n">df</span><span class="p">.</span><span class="n">moves</span> <span class="k">for</span> <span class="n">move</span> <span class="ow">in</span> <span class="n">move_set</span><span class="p">}</span>
<span class="n">weird_moves</span> <span class="o">=</span> <span class="p">{</span><span class="n">m</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">moves</span> <span class="k">if</span> <span class="s">"'"</span> <span class="ow">in</span> <span class="n">m</span><span class="p">}</span>
<span class="n">weird_moves</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
{"Baby'Doll Eyes",
"Double'Edge",
"Forest's Curse",
"Freeze'Dry",
"King's Shield",
"Land's Wrath",
"Lock'On",
"Mud'Slap",
"Multi'Attack",
"Nature's Madness",
"Power'Up Punch",
"Self'Destruct",
"Soft'Boiled",
"Topsy'Turvy",
"Trick'or'Treat",
"U'turn",
"Wake'Up Slap",
"Will'O'Wisp",
"X'Scissor"}
</pre>
</div>
<p>Many of these moves, such as U-turn, should have a dash instead of an apostrophe (according to the moves dataset). Upon closer inspection, it’s clear that the only moves that should have an apostrophe are those whose words end with an apostrophe-s. Let’s make this correction.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">weird_moves</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="s">"King's Shield"</span><span class="p">)</span>
<span class="n">weird_moves</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="s">"Forest's Curse"</span><span class="p">)</span>
<span class="n">weird_moves</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="s">"Land's Wrath"</span><span class="p">)</span>
<span class="n">weird_moves</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="s">"Nature's Madness"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">clean_moves</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span><span class="n">move</span> <span class="k">if</span> <span class="n">move</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">weird_moves</span> <span class="k">else</span>
<span class="n">move</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"'"</span><span class="p">,</span> <span class="s">"-"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">move</span> <span class="ow">in</span> <span class="n">x</span><span class="p">}</span>
<span class="n">df</span><span class="p">[</span><span class="s">'moves'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">moves</span><span class="p">.</span><span class="n">progress_map</span><span class="p">(</span><span class="n">clean_moves</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
100%|██████████| 918/918 [00:00<00:00, 43018.50it/s]
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">removal_check</span> <span class="o">=</span> <span class="p">{</span><span class="n">move</span> <span class="k">for</span> <span class="n">move_set</span> <span class="ow">in</span> <span class="n">df</span><span class="p">.</span><span class="n">moves</span>
<span class="k">for</span> <span class="n">move</span> <span class="ow">in</span> <span class="n">move_set</span>
<span class="k">if</span> <span class="s">"'"</span> <span class="ow">in</span> <span class="n">move</span><span class="p">}</span>
<span class="n">removal_check</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
{"Forest's Curse", "King's Shield", "Land's Wrath",
"Nature's Madness"}
</pre>
</div>
<p>The moves dataframe contains moves that are unlearnable by pokemon. These include moves like Struggle (which is a move pokemon use when they have no more pp in their normal moveset) and Z-moves (moves that are activated by a Z-crystal). These moves are characterized by having only 1 PP (which denotes the number of times a pokemon can use the move). Let’s remove these.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mdf</span> <span class="o">=</span> <span class="n">mdf</span><span class="p">[(</span><span class="n">mdf</span><span class="p">.</span><span class="n">pp</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">mdf</span><span class="p">.</span><span class="n">name</span> <span class="o">==</span> <span class="s">'Struggle'</span><span class="p">)]</span>
</code></pre></div></div>
<p>Due to the nature of the site we scraped, some pokemon are missing moves :(. Let’s fix part of the problem by adding back some important special moves:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'Victini'</span><span class="p">,</span> <span class="s">'moves'</span><span class="p">].</span><span class="n">add</span><span class="p">(</span><span class="s">'V-create'</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'Rayquaza'</span><span class="p">,</span> <span class="s">'moves'</span><span class="p">].</span><span class="n">add</span><span class="p">(</span><span class="s">'V-create'</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'Celebi'</span><span class="p">,</span> <span class="s">'moves'</span><span class="p">].</span><span class="n">add</span><span class="p">(</span><span class="s">'Hold Back'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">pok</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'Zygarde'</span><span class="p">,</span> <span class="s">'Zygarde-10%'</span><span class="p">,</span> <span class="s">'Zygarde-Complete'</span><span class="p">]:</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">pok</span><span class="p">,</span> <span class="s">'moves'</span><span class="p">].</span><span class="n">add</span><span class="p">(</span><span class="s">'Thousand Arrows'</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">pok</span><span class="p">,</span> <span class="s">'moves'</span><span class="p">].</span><span class="n">add</span><span class="p">(</span><span class="s">'Thousand Waves'</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">pok</span><span class="p">,</span> <span class="s">'moves'</span><span class="p">].</span><span class="n">add</span><span class="p">(</span><span class="s">'Core Enforcer'</span><span class="p">)</span>
</code></pre></div></div>
<p>Let’s say for our analysis, we only care about certain tiers. Furthermore, we want to consolidate tiers. Let’s do it:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">tier</span> <span class="o">==</span> <span class="s">'OUBL'</span><span class="p">,</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'Uber'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">tier</span> <span class="o">==</span> <span class="s">'UUBL'</span><span class="p">,</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'OU'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">tier</span> <span class="o">==</span> <span class="s">'RUBL'</span><span class="p">,</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'UU'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">tier</span> <span class="o">==</span> <span class="s">'NUBL'</span><span class="p">,</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'RU'</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">tier</span> <span class="o">==</span> <span class="s">'PUBL'</span><span class="p">,</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'NU'</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">isin</span><span class="p">([</span><span class="s">'Uber'</span><span class="p">,</span> <span class="s">'OU'</span><span class="p">,</span> <span class="s">'UU'</span><span class="p">,</span> <span class="s">'NU'</span><span class="p">,</span> <span class="s">'RU'</span><span class="p">,</span> <span class="s">'PU'</span><span class="p">])]</span>
</code></pre></div></div>
<p>The last line eliminates all pokemon that do not belong to one of those tiers (i.e. LC).</p>
<p>Since the tiers are a categorical variable, let’s covert it to the categorical dtype in pandas. This will come in handy if we decide to use this dataset in a machine learning model, as categorical variables will have a string label but have a corresponding integer code.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">astype</span><span class="p">(</span><span class="s">'category'</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">dtype</span>
</code></pre></div></div>
<p>But wait, our tiers do have an order! Let’s actually turn them into an ordered categorical variable. This will ensure the codes are in order.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pandas.api.types</span> <span class="kn">import</span> <span class="n">CategoricalDtype</span>
<span class="n">order</span> <span class="o">=</span> <span class="p">[</span><span class="s">'Uber'</span><span class="p">,</span> <span class="s">'OU'</span><span class="p">,</span> <span class="s">'UU'</span><span class="p">,</span> <span class="s">'NU'</span><span class="p">,</span> <span class="s">'RU'</span><span class="p">,</span> <span class="s">'PU'</span><span class="p">]</span>
<span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">astype</span><span class="p">(</span><span class="n">CategoricalDtype</span><span class="p">(</span><span class="n">categories</span><span class="o">=</span><span class="n">order</span><span class="p">,</span>
<span class="n">ordered</span><span class="o">=</span><span class="bp">True</span><span class="p">))</span>
<span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">dtype</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
CategoricalDtype(categories=['Uber', 'OU', 'UU', 'NU', 'RU', 'PU'], ordered=True)
</pre>
</div>
<p>We can take a look at the actual codes for the categories:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">cat</span><span class="p">.</span><span class="n">codes</span><span class="p">.</span><span class="n">head</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
name
Abomasnow 5
Abomasnow-Mega 4
Absol 5
Absol-Mega 2
Accelgor 3
Aegislash 0
Aegislash-Blade 0
Aerodactyl 4
Aerodactyl-Mega 2
Aggron 5
dtype: int8
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">list</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">head</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="n">df</span><span class="p">[</span><span class="s">'tier'</span><span class="p">].</span><span class="n">cat</span><span class="p">.</span><span class="n">codes</span><span class="p">.</span><span class="n">head</span><span class="p">(</span><span class="mi">10</span><span class="p">)))</span>
</code></pre></div></div>
<div class="output_block">
<pre class="output">
[('PU', 5),
('RU', 4),
('PU', 5),
('UU', 2),
('NU', 3),
('Uber', 0),
('Uber', 0),
('RU', 4),
('UU', 2),
('PU', 5)]
</pre>
</div>
<h2 id="very-light-feature-engineering">(very light) Feature Engineering</h2>
<p>Let’s make a feature counting the number of moves a pokemon can learn.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">[</span><span class="s">'num_moves'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">moves</span><span class="p">.</span><span class="nb">map</span><span class="p">(</span><span class="nb">len</span><span class="p">)</span>
</code></pre></div></div>
<p>The base stat total is a common metric players use to assess a Pokemon’s overall strength, so let’s create a column for this.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">[</span><span class="s">'bst'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="s">'hp'</span><span class="p">]</span> <span class="o">+</span> <span class="n">df</span><span class="p">[</span><span class="s">'atk'</span><span class="p">]</span> <span class="o">+</span> <span class="n">df</span><span class="p">[</span><span class="s">'def'</span><span class="p">]</span> <span class="o">+</span> <span class="n">df</span><span class="p">[</span><span class="s">'spa'</span><span class="p">]</span> <span class="o">+</span> <span class="n">df</span><span class="p">[</span><span class="s">'spd'</span><span class="p">]</span>
<span class="o">+</span> <span class="n">df</span><span class="p">[</span><span class="s">'spe'</span><span class="p">])</span>
</code></pre></div></div>
<h2 id="anomaly-analysis">Anomaly Analysis</h2>
<p>This workshop is about data cleaning, but a useful way to look for data issues, gain ideas for feature engineering, and understand your data is to look at anomalies. Plus, we can look at some new pandas techniques.</p>
<p>Let’s look at information about the BST by tier:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bstdf</span> <span class="o">=</span> <span class="n">df</span><span class="p">[[</span><span class="s">'tier'</span><span class="p">,</span> <span class="s">'bst'</span><span class="p">]].</span><span class="n">groupby</span><span class="p">(</span><span class="s">'tier'</span><span class="p">).</span><span class="n">agg</span><span class="p">([</span><span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">,</span> <span class="n">np</span><span class="p">.</span><span class="n">std</span><span class="p">])</span>
<span class="n">bstdf</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<style scoped="">
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead tr th {
text-align: left;
}
.dataframe thead tr:last-of-type th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr>
<th></th>
<th colspan="2" halign="left">bst</th>
</tr>
<tr>
<th></th>
<th>mean</th>
<th>std</th>
</tr>
<tr>
<th>tier</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>NU</th>
<td>495.132353</td>
<td>36.655681</td>
</tr>
<tr>
<th>OU</th>
<td>565.896104</td>
<td>68.916155</td>
</tr>
<tr>
<th>PU</th>
<td>464.184685</td>
<td>59.964976</td>
</tr>
<tr>
<th>RU</th>
<td>524.486111</td>
<td>48.101124</td>
</tr>
<tr>
<th>UU</th>
<td>538.181818</td>
<td>50.624685</td>
</tr>
<tr>
<th>Uber</th>
<td>657.042553</td>
<td>67.435946</td>
</tr>
</tbody>
</table>
</div>
<p>First, we get a dataframe containing each pokemon’s tier and base stat total. We want the mean and standard deviation of the BST’s by tier. So, we group by the tier. In pandas, we can group by multiple columns if you want. Then, we apply aggregate function mean and std. This will calculate mean and std within each tier.</p>
<p>You’ll notice that we now have a multiindex for the columns. We will not cover this in this workshop, so we will just simplify the multiindex.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bstdf</span><span class="p">.</span><span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="s">'bst_mean'</span><span class="p">,</span> <span class="s">'bst_std'</span><span class="p">]</span>
<span class="n">bstdf</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>bst_mean</th>
<th>bst_std</th>
</tr>
<tr>
<th>tier</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>NU</th>
<td>495.132353</td>
<td>36.655681</td>
</tr>
<tr>
<th>OU</th>
<td>565.896104</td>
<td>68.916155</td>
</tr>
<tr>
<th>PU</th>
<td>464.184685</td>
<td>59.964976</td>
</tr>
<tr>
<th>RU</th>
<td>524.486111</td>
<td>48.101124</td>
</tr>
<tr>
<th>UU</th>
<td>538.181818</td>
<td>50.624685</td>
</tr>
<tr>
<th>Uber</th>
<td>657.042553</td>
<td>67.435946</td>
</tr>
</tbody>
</table>
</div>
<p>The main ways to join tables in pandas are join and merge. Join is typically used to join on an index. For example, if you had two tables with the pokemon name as the index, you can do df1.join(df2), and this will horizontally concatenate the tables based on index.</p>
<p>I will show you how to use merge, which is the most general and easiest to understand joining method (though not always the fastest).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df2</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">reset_index</span><span class="p">().</span><span class="n">merge</span><span class="p">(</span><span class="n">bstdf</span><span class="p">,</span> <span class="n">left_on</span><span class="o">=</span><span class="s">'tier'</span><span class="p">,</span> <span class="n">right_on</span><span class="o">=</span><span class="s">'tier'</span><span class="p">,</span>
<span class="n">how</span><span class="o">=</span><span class="s">'left'</span><span class="p">)</span>
<span class="c1"># equivalent to bstdf.merge(df, ..., how='right')
</span><span class="n">df2</span><span class="p">.</span><span class="n">sample</span><span class="p">()</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>name</th>
<th>types</th>
<th>abilities</th>
<th>tier</th>
<th>hp</th>
<th>atk</th>
<th>def</th>
<th>spa</th>
<th>spd</th>
<th>spe</th>
<th>next_evos</th>
<th>moves</th>
<th>num_moves</th>
<th>bst</th>
<th>bst_mean</th>
<th>bst_std</th>
</tr>
</thead>
<tbody>
<tr>
<th>91</th>
<td>Crabominable</td>
<td>[Fighting, Ice]</td>
<td>[Anger Point, Hyper Cutter, Iron Fist]</td>
<td>PU</td>
<td>97</td>
<td>132</td>
<td>77</td>
<td>62</td>
<td>67</td>
<td>43</td>
<td>[]</td>
<td>{Fling, Bubble Beam, Iron Defense, Hidden Powe...</td>
<td>54</td>
<td>478</td>
<td>464.184685</td>
<td>59.964976</td>
</tr>
</tbody>
</table>
</div>
<p>Basically, pandas looked for where the tier in df equaled tier in bstdf and concatenated those rows. left_on is the column for df, right_on is the column for bstdf (in this case they’re the same). You can learn more about how joins work in this article: https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/. The concepts carry over to pandas.</p>
<p>We want to look at anomalous pokemon who’s stats seem too low for their tiers. Let’s accomplish this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">under</span> <span class="o">=</span> <span class="n">df2</span><span class="p">[(</span><span class="n">df2</span><span class="p">[</span><span class="s">'bst'</span><span class="p">]</span> <span class="o"><</span> <span class="n">df2</span><span class="p">[</span><span class="s">'bst_mean'</span><span class="p">]</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">df2</span><span class="p">[</span><span class="s">'bst_std'</span><span class="p">])</span>
<span class="o">&</span> <span class="p">(</span><span class="n">df2</span><span class="p">[</span><span class="s">'tier'</span><span class="p">]</span> <span class="o">!=</span> <span class="s">'PU'</span><span class="p">)]</span>
<span class="n">under</span>
</code></pre></div></div>
<div style="overflow-x:auto; overflow-y:auto; height: 300px;">
<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>name</th>
<th>types</th>
<th>abilities</th>
<th>tier</th>
<th>hp</th>
<th>atk</th>
<th>def</th>
<th>spa</th>
<th>spd</th>
<th>spe</th>
<th>next_evos</th>
<th>moves</th>
<th>num_moves</th>
<th>bst</th>
<th>bst_mean</th>
<th>bst_std</th>
</tr>
</thead>
<tbody>
<tr>
<th>5</th>
<td>Aegislash</td>
<td>[Steel, Ghost]</td>
<td>[Stance Change]</td>
<td>Uber</td>
<td>60</td>
<td>50</td>
<td>150</td>
<td>50</td>
<td>150</td>
<td>60</td>
<td>[]</td>
<td>{Hidden Power, Iron Defense, Hyper Beam, Pursu...</td>
<td>55</td>
<td>520</td>
<td>657.042553</td>
<td>67.435946</td>
</tr>
<tr>
<th>6</th>
<td>Aegislash-Blade</td>
<td>[Steel, Ghost]</td>
<td>[Stance Change]</td>
<td>Uber</td>
<td>60</td>
<td>150</td>
<td>50</td>
<td>150</td>
<td>50</td>
<td>60</td>
<td>[]</td>
<td>{Hidden Power, Iron Defense, Hyper Beam, Pursu...</td>
<td>55</td>
<td>520</td>
<td>657.042553</td>
<td>67.435946</td>
</tr>
<tr>
<th>34</th>
<td>Azumarill</td>
<td>[Water, Fairy]</td>
<td>[Huge Power, Sap Sipper, Thick Fat]</td>
<td>OU</td>
<td>100</td>
<td>50</td>
<td>80</td>
<td>60</td>
<td>80</td>
<td>50</td>
<td>[]</td>
<td>{Muddy Water, Swagger, Water Pulse, Ice Beam, ...</td>
<td>96</td>
<td>420</td>
<td>565.896104</td>
<td>68.916155</td>
</tr>
<tr>
<th>115</th>
<td>Diggersby</td>
<td>[Normal, Ground]</td>
<td>[Cheek Pouch, Huge Power, Pickup]</td>
<td>OU</td>
<td>85</td>
<td>56</td>
<td>77</td>
<td>50</td>
<td>77</td>
<td>78</td>
<td>[]</td>
<td>{Rollout, Sandstorm, Fling, Earthquake, Hidden...</td>
<td>81</td>
<td>423</td>
<td>565.896104</td>
<td>68.916155</td>
</tr>
<tr>
<th>267</th>
<td>Linoone</td>
<td>[Normal]</td>
<td>[Gluttony, Pickup, Quick Feet]</td>
<td>RU</td>
<td>78</td>
<td>70</td>
<td>61</td>
<td>50</td>
<td>61</td>
<td>100</td>
<td>[]</td>
<td>{Thunder Wave, Super Fang, Swagger, Water Puls...</td>
<td>89</td>
<td>420</td>
<td>524.486111</td>
<td>48.101124</td>
</tr>
<tr>
<th>298</th>
<td>Marowak-Alola</td>
<td>[Fire, Ghost]</td>
<td>[Cursed Body, Lightning Rod, Rock Head]</td>
<td>UU</td>
<td>60</td>
<td>80</td>
<td>110</td>
<td>50</td>
<td>80</td>
<td>45</td>
<td>[]</td>
<td>{Tail Whip, Sandstorm, Fling, Hidden Power, Hy...</td>
<td>74</td>
<td>425</td>
<td>538.181818</td>
<td>50.624685</td>
</tr>
<tr>
<th>303</th>
<td>Medicham</td>
<td>[Fighting, Psychic]</td>
<td>[Pure Power, Telepathy]</td>
<td>NU</td>
<td>60</td>
<td>60</td>
<td>75</td>
<td>60</td>
<td>75</td>
<td>80</td>
<td>[]</td>
<td>{Rock Slide, Swagger, Meditate, Confusion, Gra...</td>
<td>96</td>
<td>410</td>
<td>495.132353</td>
<td>36.655681</td>
</tr>
<tr>
<th>521</th>
<td>Vivillon</td>
<td>[Bug, Flying]</td>
<td>[Compound Eyes, Friend Guard, Shield Dust]</td>
<td>NU</td>
<td>80</td>
<td>52</td>
<td>50</td>
<td>90</td>
<td>50</td>
<td>89</td>
<td>[]</td>
<td>{Hidden Power, Iron Defense, Hyper Beam, Rest,...</td>
<td>59</td>
<td>411</td>
<td>495.132353</td>
<td>36.655681</td>
</tr>
</tbody>
</table>
</div>
<h2 id="misc">Misc.</h2>
<p>Pandas also has built in graphing functionalities which behave identically to matplotlib. For example:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">bst</span><span class="p">.</span><span class="n">hist</span><span class="p">()</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-pandas/Introduction_to_Data_Cleaning_with_Pandas_96_1.png#center" alt="png" /></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">plot</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="s">'bst'</span><span class="p">,</span> <span class="s">'atk'</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-pandas/Introduction_to_Data_Cleaning_with_Pandas_97_1.png#center" alt="png" /></p>
<p>Finally, we can “pivot” tables as you would in excel. This provides a summary of the data.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">[</span><span class="s">'type_1'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">'types'</span><span class="p">].</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">pd</span><span class="p">.</span><span class="n">pivot_table</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="s">'tier'</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="s">'type_1'</span><span class="p">,</span> <span class="n">values</span><span class="o">=</span><span class="s">'bst'</span><span class="p">,</span>
<span class="n">aggfunc</span><span class="o">=</span><span class="s">'mean'</span><span class="p">)</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>type_1</th>
<th>Bug</th>
<th>Dark</th>
<th>Dragon</th>
<th>Electric</th>
<th>Fairy</th>
<th>Fighting</th>
<th>Fire</th>
<th>Flying</th>
<th>Ghost</th>
<th>Grass</th>
<th>Ground</th>
<th>Ice</th>
<th>Normal</th>
<th>Poison</th>
<th>Psychic</th>
<th>Rock</th>
<th>Steel</th>
<th>Water</th>
</tr>
<tr>
<th>tier</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>NU</th>
<td>476.500000</td>
<td>494.000000</td>
<td>487.500000</td>
<td>460.500000</td>
<td>473.500000</td>
<td>469.625000</td>
<td>534.400000</td>
<td>479.000000</td>
<td>483.750000</td>
<td>506.250000</td>
<td>486.250</td>
<td>525.000000</td>
<td>495.400000</td>
<td>457.0</td>
<td>520.000000</td>
<td>519.50</td>
<td>520.000000</td>
<td>520.750000</td>
</tr>
<tr>
<th>OU</th>
<td>567.500000</td>
<td>520.000000</td>
<td>644.444444</td>
<td>562.142857</td>
<td>483.000000</td>
<td>524.250000</td>
<td>607.600000</td>
<td>518.333333</td>
<td>476.000000</td>
<td>542.166667</td>
<td>519.000</td>
<td>505.000000</td>
<td>497.000000</td>
<td>495.0</td>
<td>598.250000</td>
<td>700.00</td>
<td>550.000000</td>
<td>576.428571</td>
</tr>
<tr>
<th>PU</th>
<td>426.521739</td>
<td>448.300000</td>
<td>NaN</td>
<td>473.800000</td>
<td>392.666667</td>
<td>461.333333</td>
<td>485.454545</td>
<td>447.090909</td>
<td>479.400000</td>
<td>478.476190</td>
<td>457.875</td>
<td>511.727273</td>
<td>457.342857</td>
<td>472.6</td>
<td>465.266667</td>
<td>494.00</td>
<td>380.000000</td>
<td>459.000000</td>
</tr>
<tr>
<th>RU</th>
<td>490.166667</td>
<td>510.000000</td>
<td>536.500000</td>
<td>543.750000</td>
<td>516.000000</td>
<td>527.000000</td>
<td>573.333333</td>
<td>495.000000</td>
<td>518.333333</td>
<td>546.500000</td>
<td>480.000</td>
<td>552.500000</td>
<td>523.571429</td>
<td>487.0</td>
<td>545.428571</td>
<td>505.75</td>
<td>546.000000</td>
<td>538.500000</td>
</tr>
<tr>
<th>UU</th>
<td>485.800000</td>
<td>531.714286</td>
<td>598.000000</td>
<td>540.000000</td>
<td>525.000000</td>
<td>531.500000</td>
<td>517.000000</td>
<td>536.250000</td>
<td>500.000000</td>
<td>586.000000</td>
<td>512.250</td>
<td>NaN</td>
<td>559.500000</td>
<td>507.5</td>
<td>547.500000</td>
<td>585.00</td>
<td>543.333333</td>
<td>544.166667</td>
</tr>
<tr>
<th>Uber</th>
<td>585.000000</td>
<td>640.000000</td>
<td>686.800000</td>
<td>NaN</td>
<td>680.000000</td>
<td>612.500000</td>
<td>613.333333</td>
<td>626.666667</td>
<td>600.000000</td>
<td>NaN</td>
<td>720.000</td>
<td>NaN</td>
<td>655.000000</td>
<td>540.0</td>
<td>682.153846</td>
<td>NaN</td>
<td>580.000000</td>
<td>720.000000</td>
</tr>
</tbody>
</table>
</div>
<h2 id="conclusion">Conclusion</h2>
<p>Through this workshop, we’ve seen an overview of pandas and how it can be useful for data preprocessing. Next, we can use these skills to analyze and model our data using <a href="https://nicholasvadivelu.com/2019/09/27/intro-to-random-forests/">random forests in scikit-learn</a>.</p>Nicholas Vadivelunicholas.vadivelu@gmail.comThrough this workshop, you will learn how to use Pandas to explore and “wrangle” datasets. Topics will include an introduction to Jupyter Notebooks/Colab, data cleaning with pandas, feature engineering with pandas, basic visualization and more. This workshop will focus on actual coding.Introduction to Random Forests2019-09-27T00:00:00+00:002019-09-27T00:00:00+00:00https://nicholasvadivelu.com/2019/09/27/intro-to-random-forests<p>Through this workshop you will learn how to quickly model and understand datasets using scikit-learn. Topics will include a basic introduction to using decisions trees and random forests, understanding feature importance, identifying model weaknesses, explaining your model, and more.</p>
<p>If you are not familiar with pandas, check out <a href="https://nicholasvadivelu.com/2019/09/27/intro-to-pandas/">this</a> post first. This article contains some high level explanations of the code not covered in the live workshop, but skips some examples given in the main presentation. <a href="https://youtu.be/ANdn3CF4bss">Here</a> is a recording of the main workshop, <a href="https://docs.google.com/presentation/d/14e5iw-AswCbli4YUHZI1d9OYu4csM2nyxv84Ytu68QY">here</a> are the slides, and <a href="https://colab.research.google.com/github/n2cholas/dsc-workshops/blob/master/Random_Forests_Workshop_V2.ipynb">here</a> is a colab link to run all the code.</p>
<p>Many of the model interpretation techniques were taken from the <a href="http://course18.fast.ai/ml">fast.ai ML course</a>. Check it out!!</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">import</span> <span class="nn">seaborn</span> <span class="k">as</span> <span class="n">sns</span>
<span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
</code></pre></div></div>
<h2 id="data-wrangling">Data Wrangling</h2>
<p>Data munging/wrangling is the process of transforming your raw data into a form suitable for analysis or modelling. Typically this involves dealing with null values, finding (and possibly correcting) data issues, transforming non-numerical data into numerical data, and more.</p>
<p>In the “real world”, you will need to do much more than is shown below. There are numerous Kaggle Kernels demonstrating in depth data cleaning. For the purposes of this workshop, we will do (less than) the bare minimum for two reasons:</p>
<ol>
<li>We are using a relatively clean dataset (with few data oddities).</li>
<li>Our model analysis will tell us where to focus our data cleaning and feature engineering efforts.</li>
<li>This workshop is only an hour long :P.</li>
</ol>
<p><a href="https://www.kaggle.com/pmarcelino/comprehensive-data-exploration-with-python">Here</a> is an example of a great example of some data exploration and correction.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">show_all</span><span class="p">(</span><span class="n">df</span><span class="p">):</span>
<span class="s">"""Shows our dataframe without cutting off any rows or columns."""</span>
<span class="k">with</span> <span class="n">pd</span><span class="p">.</span><span class="n">option_context</span><span class="p">(</span><span class="s">"display.max_rows"</span><span class="p">,</span> <span class="mi">1000</span><span class="p">,</span>
<span class="s">"display.max_columns"</span><span class="p">,</span> <span class="mi">1000</span><span class="p">):</span>
<span class="n">display</span><span class="p">(</span><span class="n">df</span><span class="p">)</span>
</code></pre></div></div>
<p>First, we take a look at our data to get a sense of the types of values in the columns. We do this by looking at some of our data and using numerical summaries.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'https://raw.githubusercontent.com/n2cholas/dsc-workshops/master/Random%20Forest%20Workshop/data/train.csv'</span><span class="p">)</span>
<span class="n">show_all</span><span class="p">(</span><span class="n">df</span><span class="p">.</span><span class="n">head</span><span class="p">())</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Id</th>
<th>MSSubClass</th>
<th>MSZoning</th>
<th>LotFrontage</th>
<th>LotArea</th>
<th>Street</th>
<th>Alley</th>
<th>LotShape</th>
<th>LandContour</th>
<th>Utilities</th>
<th>LotConfig</th>
<th>LandSlope</th>
<th>Neighborhood</th>
<th>Condition1</th>
<th>Condition2</th>
<th>BldgType</th>
<th>HouseStyle</th>
<th>OverallQual</th>
<th>OverallCond</th>
<th>YearBuilt</th>
<th>YearRemodAdd</th>
<th>RoofStyle</th>
<th>RoofMatl</th>
<th>Exterior1st</th>
<th>Exterior2nd</th>
<th>MasVnrType</th>
<th>MasVnrArea</th>
<th>ExterQual</th>
<th>ExterCond</th>
<th>Foundation</th>
<th>BsmtQual</th>
<th>BsmtCond</th>
<th>BsmtExposure</th>
<th>BsmtFinType1</th>
<th>BsmtFinSF1</th>
<th>BsmtFinType2</th>
<th>BsmtFinSF2</th>
<th>BsmtUnfSF</th>
<th>TotalBsmtSF</th>
<th>Heating</th>
<th>HeatingQC</th>
<th>CentralAir</th>
<th>Electrical</th>
<th>1stFlrSF</th>
<th>2ndFlrSF</th>
<th>LowQualFinSF</th>
<th>GrLivArea</th>
<th>BsmtFullBath</th>
<th>BsmtHalfBath</th>
<th>FullBath</th>
<th>HalfBath</th>
<th>BedroomAbvGr</th>
<th>KitchenAbvGr</th>
<th>KitchenQual</th>
<th>TotRmsAbvGrd</th>
<th>Functional</th>
<th>Fireplaces</th>
<th>FireplaceQu</th>
<th>GarageType</th>
<th>GarageYrBlt</th>
<th>GarageFinish</th>
<th>GarageCars</th>
<th>GarageArea</th>
<th>GarageQual</th>
<th>GarageCond</th>
<th>PavedDrive</th>
<th>WoodDeckSF</th>
<th>OpenPorchSF</th>
<th>EnclosedPorch</th>
<th>3SsnPorch</th>
<th>ScreenPorch</th>
<th>PoolArea</th>
<th>PoolQC</th>
<th>Fence</th>
<th>MiscFeature</th>
<th>MiscVal</th>
<th>MoSold</th>
<th>YrSold</th>
<th>SaleType</th>
<th>SaleCondition</th>
<th>SalePrice</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1</td>
<td>60</td>
<td>RL</td>
<td>65.0</td>
<td>8450</td>
<td>Pave</td>
<td>NaN</td>
<td>Reg</td>
<td>Lvl</td>
<td>AllPub</td>
<td>Inside</td>
<td>Gtl</td>
<td>CollgCr</td>
<td>Norm</td>
<td>Norm</td>
<td>1Fam</td>
<td>2Story</td>
<td>7</td>
<td>5</td>
<td>2003</td>
<td>2003</td>
<td>Gable</td>
<td>CompShg</td>
<td>VinylSd</td>
<td>VinylSd</td>
<td>BrkFace</td>
<td>196.0</td>
<td>Gd</td>
<td>TA</td>
<td>PConc</td>
<td>Gd</td>
<td>TA</td>
<td>No</td>
<td>GLQ</td>
<td>706</td>
<td>Unf</td>
<td>0</td>
<td>150</td>
<td>856</td>
<td>GasA</td>
<td>Ex</td>
<td>Y</td>
<td>SBrkr</td>
<td>856</td>
<td>854</td>
<td>0</td>
<td>1710</td>
<td>1</td>
<td>0</td>
<td>2</td>
<td>1</td>
<td>3</td>
<td>1</td>
<td>Gd</td>
<td>8</td>
<td>Typ</td>
<td>0</td>
<td>NaN</td>
<td>Attchd</td>
<td>2003.0</td>
<td>RFn</td>
<td>2</td>
<td>548</td>
<td>TA</td>
<td>TA</td>
<td>Y</td>
<td>0</td>
<td>61</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>0</td>
<td>2</td>
<td>2008</td>
<td>WD</td>
<td>Normal</td>
<td>208500</td>
</tr>
<tr>
<th>1</th>
<td>2</td>
<td>20</td>
<td>RL</td>
<td>80.0</td>
<td>9600</td>
<td>Pave</td>
<td>NaN</td>
<td>Reg</td>
<td>Lvl</td>
<td>AllPub</td>
<td>FR2</td>
<td>Gtl</td>
<td>Veenker</td>
<td>Feedr</td>
<td>Norm</td>
<td>1Fam</td>
<td>1Story</td>
<td>6</td>
<td>8</td>
<td>1976</td>
<td>1976</td>
<td>Gable</td>
<td>CompShg</td>
<td>MetalSd</td>
<td>MetalSd</td>
<td>None</td>
<td>0.0</td>
<td>TA</td>
<td>TA</td>
<td>CBlock</td>
<td>Gd</td>
<td>TA</td>
<td>Gd</td>
<td>ALQ</td>
<td>978</td>
<td>Unf</td>
<td>0</td>
<td>284</td>
<td>1262</td>
<td>GasA</td>
<td>Ex</td>
<td>Y</td>
<td>SBrkr</td>
<td>1262</td>
<td>0</td>
<td>0</td>
<td>1262</td>
<td>0</td>
<td>1</td>
<td>2</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>TA</td>
<td>6</td>
<td>Typ</td>
<td>1</td>
<td>TA</td>
<td>Attchd</td>
<td>1976.0</td>
<td>RFn</td>
<td>2</td>
<td>460</td>
<td>TA</td>
<td>TA</td>
<td>Y</td>
<td>298</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>0</td>
<td>5</td>
<td>2007</td>
<td>WD</td>
<td>Normal</td>
<td>181500</td>
</tr>
<tr>
<th>2</th>
<td>3</td>
<td>60</td>
<td>RL</td>
<td>68.0</td>
<td>11250</td>
<td>Pave</td>
<td>NaN</td>
<td>IR1</td>
<td>Lvl</td>
<td>AllPub</td>
<td>Inside</td>
<td>Gtl</td>
<td>CollgCr</td>
<td>Norm</td>
<td>Norm</td>
<td>1Fam</td>
<td>2Story</td>
<td>7</td>
<td>5</td>
<td>2001</td>
<td>2002</td>
<td>Gable</td>
<td>CompShg</td>
<td>VinylSd</td>
<td>VinylSd</td>
<td>BrkFace</td>
<td>162.0</td>
<td>Gd</td>
<td>TA</td>
<td>PConc</td>
<td>Gd</td>
<td>TA</td>
<td>Mn</td>
<td>GLQ</td>
<td>486</td>
<td>Unf</td>
<td>0</td>
<td>434</td>
<td>920</td>
<td>GasA</td>
<td>Ex</td>
<td>Y</td>
<td>SBrkr</td>
<td>920</td>
<td>866</td>
<td>0</td>
<td>1786</td>
<td>1</td>
<td>0</td>
<td>2</td>
<td>1</td>
<td>3</td>
<td>1</td>
<td>Gd</td>
<td>6</td>
<td>Typ</td>
<td>1</td>
<td>TA</td>
<td>Attchd</td>
<td>2001.0</td>
<td>RFn</td>
<td>2</td>
<td>608</td>
<td>TA</td>
<td>TA</td>
<td>Y</td>
<td>0</td>
<td>42</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>0</td>
<td>9</td>
<td>2008</td>
<td>WD</td>
<td>Normal</td>
<td>223500</td>
</tr>
<tr>
<th>3</th>
<td>4</td>
<td>70</td>
<td>RL</td>
<td>60.0</td>
<td>9550</td>
<td>Pave</td>
<td>NaN</td>
<td>IR1</td>
<td>Lvl</td>
<td>AllPub</td>
<td>Corner</td>
<td>Gtl</td>
<td>Crawfor</td>
<td>Norm</td>
<td>Norm</td>
<td>1Fam</td>
<td>2Story</td>
<td>7</td>
<td>5</td>
<td>1915</td>
<td>1970</td>
<td>Gable</td>
<td>CompShg</td>
<td>Wd Sdng</td>
<td>Wd Shng</td>
<td>None</td>
<td>0.0</td>
<td>TA</td>
<td>TA</td>
<td>BrkTil</td>
<td>TA</td>
<td>Gd</td>
<td>No</td>
<td>ALQ</td>
<td>216</td>
<td>Unf</td>
<td>0</td>
<td>540</td>
<td>756</td>
<td>GasA</td>
<td>Gd</td>
<td>Y</td>
<td>SBrkr</td>
<td>961</td>
<td>756</td>
<td>0</td>
<td>1717</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>Gd</td>
<td>7</td>
<td>Typ</td>
<td>1</td>
<td>Gd</td>
<td>Detchd</td>
<td>1998.0</td>
<td>Unf</td>
<td>3</td>
<td>642</td>
<td>TA</td>
<td>TA</td>
<td>Y</td>
<td>0</td>
<td>35</td>
<td>272</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>0</td>
<td>2</td>
<td>2006</td>
<td>WD</td>
<td>Abnorml</td>
<td>140000</td>
</tr>
<tr>
<th>4</th>
<td>5</td>
<td>60</td>
<td>RL</td>
<td>84.0</td>
<td>14260</td>
<td>Pave</td>
<td>NaN</td>
<td>IR1</td>
<td>Lvl</td>
<td>AllPub</td>
<td>FR2</td>
<td>Gtl</td>
<td>NoRidge</td>
<td>Norm</td>
<td>Norm</td>
<td>1Fam</td>
<td>2Story</td>
<td>8</td>
<td>5</td>
<td>2000</td>
<td>2000</td>
<td>Gable</td>
<td>CompShg</td>
<td>VinylSd</td>
<td>VinylSd</td>
<td>BrkFace</td>
<td>350.0</td>
<td>Gd</td>
<td>TA</td>
<td>PConc</td>
<td>Gd</td>
<td>TA</td>
<td>Av</td>
<td>GLQ</td>
<td>655</td>
<td>Unf</td>
<td>0</td>
<td>490</td>
<td>1145</td>
<td>GasA</td>
<td>Ex</td>
<td>Y</td>
<td>SBrkr</td>
<td>1145</td>
<td>1053</td>
<td>0</td>
<td>2198</td>
<td>1</td>
<td>0</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>1</td>
<td>Gd</td>
<td>9</td>
<td>Typ</td>
<td>1</td>
<td>TA</td>
<td>Attchd</td>
<td>2000.0</td>
<td>RFn</td>
<td>3</td>
<td>836</td>
<td>TA</td>
<td>TA</td>
<td>Y</td>
<td>192</td>
<td>84</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>0</td>
<td>12</td>
<td>2008</td>
<td>WD</td>
<td>Normal</td>
<td>250000</td>
</tr>
</tbody>
</table>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">len</span><span class="p">(</span><span class="n">df</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">1460</code>
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">show_all</span><span class="p">(</span><span class="n">df</span><span class="p">.</span><span class="n">describe</span><span class="p">())</span>
</code></pre></div></div>
<div style="overflow-x:auto;">
<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>Id</th>
<th>MSSubClass</th>
<th>LotFrontage</th>
<th>LotArea</th>
<th>OverallQual</th>
<th>OverallCond</th>
<th>YearBuilt</th>
<th>YearRemodAdd</th>
<th>MasVnrArea</th>
<th>BsmtFinSF1</th>
<th>BsmtFinSF2</th>
<th>BsmtUnfSF</th>
<th>TotalBsmtSF</th>
<th>1stFlrSF</th>
<th>2ndFlrSF</th>
<th>LowQualFinSF</th>
<th>GrLivArea</th>
<th>BsmtFullBath</th>
<th>BsmtHalfBath</th>
<th>FullBath</th>
<th>HalfBath</th>
<th>BedroomAbvGr</th>
<th>KitchenAbvGr</th>
<th>TotRmsAbvGrd</th>
<th>Fireplaces</th>
<th>GarageYrBlt</th>
<th>GarageCars</th>
<th>GarageArea</th>
<th>WoodDeckSF</th>
<th>OpenPorchSF</th>
<th>EnclosedPorch</th>
<th>3SsnPorch</th>
<th>ScreenPorch</th>
<th>PoolArea</th>
<th>MiscVal</th>
<th>MoSold</th>
<th>YrSold</th>
<th>SalePrice</th>
</tr>
</thead>
<tbody>
<tr>
<th>count</th>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1201.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1452.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1379.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
<td>1460.000000</td>
</tr>
<tr>
<th>mean</th>
<td>730.500000</td>
<td>56.897260</td>
<td>70.049958</td>
<td>10516.828082</td>
<td>6.099315</td>
<td>5.575342</td>
<td>1971.267808</td>
<td>1984.865753</td>
<td>103.685262</td>
<td>443.639726</td>
<td>46.549315</td>
<td>567.240411</td>
<td>1057.429452</td>
<td>1162.626712</td>
<td>346.992466</td>
<td>5.844521</td>
<td>1515.463699</td>
<td>0.425342</td>
<td>0.057534</td>
<td>1.565068</td>
<td>0.382877</td>
<td>2.866438</td>
<td>1.046575</td>
<td>6.517808</td>
<td>0.613014</td>
<td>1978.506164</td>
<td>1.767123</td>
<td>472.980137</td>
<td>94.244521</td>
<td>46.660274</td>
<td>21.954110</td>
<td>3.409589</td>
<td>15.060959</td>
<td>2.758904</td>
<td>43.489041</td>
<td>6.321918</td>
<td>2007.815753</td>
<td>180921.195890</td>
</tr>
<tr>
<th>std</th>
<td>421.610009</td>
<td>42.300571</td>
<td>24.284752</td>
<td>9981.264932</td>
<td>1.382997</td>
<td>1.112799</td>
<td>30.202904</td>
<td>20.645407</td>
<td>181.066207</td>
<td>456.098091</td>
<td>161.319273</td>
<td>441.866955</td>
<td>438.705324</td>
<td>386.587738</td>
<td>436.528436</td>
<td>48.623081</td>
<td>525.480383</td>
<td>0.518911</td>
<td>0.238753</td>
<td>0.550916</td>
<td>0.502885</td>
<td>0.815778</td>
<td>0.220338</td>
<td>1.625393</td>
<td>0.644666</td>
<td>24.689725</td>
<td>0.747315</td>
<td>213.804841</td>
<td>125.338794</td>
<td>66.256028</td>
<td>61.119149</td>
<td>29.317331</td>
<td>55.757415</td>
<td>40.177307</td>
<td>496.123024</td>
<td>2.703626</td>
<td>1.328095</td>
<td>79442.502883</td>
</tr>
<tr>
<th>min</th>
<td>1.000000</td>
<td>20.000000</td>
<td>21.000000</td>
<td>1300.000000</td>
<td>1.000000</td>
<td>1.000000</td>
<td>1872.000000</td>
<td>1950.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>334.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>334.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>2.000000</td>
<td>0.000000</td>
<td>1900.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>1.000000</td>
<td>2006.000000</td>
<td>34900.000000</td>
</tr>
<tr>
<th>25%</th>
<td>365.750000</td>
<td>20.000000</td>
<td>59.000000</td>
<td>7553.500000</td>
<td>5.000000</td>
<td>5.000000</td>
<td>1954.000000</td>
<td>1967.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>223.000000</td>
<td>795.750000</td>
<td>882.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>1129.500000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>1.000000</td>
<td>0.000000</td>
<td>2.000000</td>
<td>1.000000</td>
<td>5.000000</td>
<td>0.000000</td>
<td>1961.000000</td>
<td>1.000000</td>
<td>334.500000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>5.000000</td>
<td>2007.000000</td>
<td>129975.000000</td>
</tr>
<tr>
<th>50%</th>
<td>730.500000</td>
<td>50.000000</td>
<td>69.000000</td>
<td>9478.500000</td>
<td>6.000000</td>
<td>5.000000</td>
<td>1973.000000</td>
<td>1994.000000</td>
<td>0.000000</td>
<td>383.500000</td>
<td>0.000000</td>
<td>477.500000</td>
<td>991.500000</td>
<td>1087.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>1464.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>2.000000</td>
<td>0.000000</td>
<td>3.000000</td>
<td>1.000000</td>
<td>6.000000</td>
<td>1.000000</td>
<td>1980.000000</td>
<td>2.000000</td>
<td>480.000000</td>
<td>0.000000</td>
<td>25.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>6.000000</td>
<td>2008.000000</td>
<td>163000.000000</td>
</tr>
<tr>
<th>75%</th>
<td>1095.250000</td>
<td>70.000000</td>
<td>80.000000</td>
<td>11601.500000</td>
<td>7.000000</td>
<td>6.000000</td>
<td>2000.000000</td>
<td>2004.000000</td>
<td>166.000000</td>
<td>712.250000</td>
<td>0.000000</td>
<td>808.000000</td>
<td>1298.250000</td>
<td>1391.250000</td>
<td>728.000000</td>
<td>0.000000</td>
<td>1776.750000</td>
<td>1.000000</td>
<td>0.000000</td>
<td>2.000000</td>
<td>1.000000</td>
<td>3.000000</td>
<td>1.000000</td>
<td>7.000000</td>
<td>1.000000</td>
<td>2002.000000</td>
<td>2.000000</td>
<td>576.000000</td>
<td>168.000000</td>
<td>68.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>0.000000</td>
<td>8.000000</td>
<td>2009.000000</td>
<td>214000.000000</td>
</tr>
<tr>
<th>max</th>
<td>1460.000000</td>
<td>190.000000</td>
<td>313.000000</td>
<td>215245.000000</td>
<td>10.000000</td>
<td>9.000000</td>
<td>2010.000000</td>
<td>2010.000000</td>
<td>1600.000000</td>
<td>5644.000000</td>
<td>1474.000000</td>
<td>2336.000000</td>
<td>6110.000000</td>
<td>4692.000000</td>
<td>2065.000000</td>
<td>572.000000</td>
<td>5642.000000</td>
<td>3.000000</td>
<td>2.000000</td>
<td>3.000000</td>
<td>2.000000</td>
<td>8.000000</td>
<td>3.000000</td>
<td>14.000000</td>
<td>3.000000</td>
<td>2010.000000</td>
<td>4.000000</td>
<td>1418.000000</td>
<td>857.000000</td>
<td>547.000000</td>
<td>552.000000</td>
<td>508.000000</td>
<td>480.000000</td>
<td>738.000000</td>
<td>15500.000000</td>
<td>12.000000</td>
<td>2010.000000</td>
<td>755000.000000</td>
</tr>
</tbody>
</table>
</div>
<p>We want to ensure all our columns (or features) have numerical or categorical values. Let’s look at the data types of each column.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">show_all</span><span class="p">(</span><span class="n">df</span><span class="p">.</span><span class="n">dtypes</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">Id int64
MSSubClass int64
MSZoning object
LotFrontage float64
LotArea int64
Street object
Alley object
LotShape object
LandContour object
Utilities object
LotConfig object
LandSlope object
Neighborhood object
Condition1 object
Condition2 object
BldgType object
HouseStyle object
OverallQual int64
OverallCond int64
YearBuilt int64
YearRemodAdd int64
RoofStyle object
RoofMatl object
Exterior1st object
Exterior2nd object
MasVnrType object
MasVnrArea float64
ExterQual object
ExterCond object
Foundation object
BsmtQual object
BsmtCond object
BsmtExposure object
BsmtFinType1 object
BsmtFinSF1 int64
BsmtFinType2 object
BsmtFinSF2 int64
BsmtUnfSF int64
TotalBsmtSF int64
Heating object
HeatingQC object
CentralAir object
Electrical object
1stFlrSF int64
2ndFlrSF int64
LowQualFinSF int64
GrLivArea int64
BsmtFullBath int64
BsmtHalfBath int64
FullBath int64
HalfBath int64
BedroomAbvGr int64
KitchenAbvGr int64
KitchenQual object
TotRmsAbvGrd int64
Functional object
Fireplaces int64
FireplaceQu object
GarageType object
GarageYrBlt float64
GarageFinish object
GarageCars int64
GarageArea int64
GarageQual object
GarageCond object
PavedDrive object
WoodDeckSF int64
OpenPorchSF int64
EnclosedPorch int64
3SsnPorch int64
ScreenPorch int64
PoolArea int64
PoolQC object
Fence object
MiscFeature object
MiscVal int64
MoSold int64
YrSold int64
SaleType object
SaleCondition object
SalePrice int64
dtype: object</code>
</pre>
</div>
<p>Most of the data is of type <code class="language-plaintext highlighter-rouge">object</code>. In general, this will be a Python string but could also be other Python objects, such as lists or dicts. Just based on the names, it looks like these are all categorical features. Let’s check this by looking at the unique values in each column.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">df</span><span class="p">.</span><span class="n">columns</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">dtypes</span><span class="o">==</span><span class="s">'object'</span><span class="p">]:</span>
<span class="k">print</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="n">c</span><span class="p">].</span><span class="n">value_counts</span><span class="p">())</span>
<span class="k">print</span><span class="p">()</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">RL 1151
RM 218
FV 65
RH 16
C (all) 10
Name: MSZoning, dtype: int64
Pave 1454
Grvl 6
Name: Street, dtype: int64
Grvl 50
Pave 41
Name: Alley, dtype: int64
Reg 925
IR1 484
IR2 41
IR3 10
Name: LotShape, dtype: int64
Lvl 1311
Bnk 63
HLS 50
Low 36
Name: LandContour, dtype: int64
AllPub 1459
NoSeWa 1
Name: Utilities, dtype: int64
Inside 1052
Corner 263
CulDSac 94
FR2 47
FR3 4
Name: LotConfig, dtype: int64
Gtl 1382
Mod 65
Sev 13
Name: LandSlope, dtype: int64
NAmes 225
CollgCr 150
OldTown 113
Edwards 100
Somerst 86
Gilbert 79
NridgHt 77
Sawyer 74
NWAmes 73
SawyerW 59
BrkSide 58
Crawfor 51
Mitchel 49
NoRidge 41
Timber 38
IDOTRR 37
ClearCr 28
StoneBr 25
SWISU 25
MeadowV 17
Blmngtn 17
BrDale 16
Veenker 11
NPkVill 9
Blueste 2
Name: Neighborhood, dtype: int64
Norm 1260
Feedr 81
Artery 48
RRAn 26
PosN 19
RRAe 11
PosA 8
RRNn 5
RRNe 2
Name: Condition1, dtype: int64
Norm 1445
Feedr 6
RRNn 2
PosN 2
Artery 2
RRAe 1
PosA 1
RRAn 1
Name: Condition2, dtype: int64
1Fam 1220
TwnhsE 114
Duplex 52
Twnhs 43
2fmCon 31
Name: BldgType, dtype: int64
1Story 726
2Story 445
1.5Fin 154
SLvl 65
SFoyer 37
1.5Unf 14
2.5Unf 11
2.5Fin 8
Name: HouseStyle, dtype: int64
Gable 1141
Hip 286
Flat 13
Gambrel 11
Mansard 7
Shed 2
Name: RoofStyle, dtype: int64
CompShg 1434
Tar&Grv 11
WdShngl 6
WdShake 5
Membran 1
Roll 1
ClyTile 1
Metal 1
Name: RoofMatl, dtype: int64
VinylSd 515
HdBoard 222
MetalSd 220
Wd Sdng 206
Plywood 108
CemntBd 61
BrkFace 50
WdShing 26
Stucco 25
AsbShng 20
Stone 2
BrkComm 2
AsphShn 1
ImStucc 1
CBlock 1
Name: Exterior1st, dtype: int64
VinylSd 504
MetalSd 214
HdBoard 207
Wd Sdng 197
Plywood 142
CmentBd 60
Wd Shng 38
Stucco 26
BrkFace 25
AsbShng 20
ImStucc 10
Brk Cmn 7
Stone 5
AsphShn 3
CBlock 1
Other 1
Name: Exterior2nd, dtype: int64
None 864
BrkFace 445
Stone 128
BrkCmn 15
Name: MasVnrType, dtype: int64
TA 906
Gd 488
Ex 52
Fa 14
Name: ExterQual, dtype: int64
TA 1282
Gd 146
Fa 28
Ex 3
Po 1
Name: ExterCond, dtype: int64
PConc 647
CBlock 634
BrkTil 146
Slab 24
Stone 6
Wood 3
Name: Foundation, dtype: int64
TA 649
Gd 618
Ex 121
Fa 35
Name: BsmtQual, dtype: int64
TA 1311
Gd 65
Fa 45
Po 2
Name: BsmtCond, dtype: int64
No 953
Av 221
Gd 134
Mn 114
Name: BsmtExposure, dtype: int64
Unf 430
GLQ 418
ALQ 220
BLQ 148
Rec 133
LwQ 74
Name: BsmtFinType1, dtype: int64
Unf 1256
Rec 54
LwQ 46
BLQ 33
ALQ 19
GLQ 14
Name: BsmtFinType2, dtype: int64
GasA 1428
GasW 18
Grav 7
Wall 4
OthW 2
Floor 1
Name: Heating, dtype: int64
Ex 741
TA 428
Gd 241
Fa 49
Po 1
Name: HeatingQC, dtype: int64
Y 1365
N 95
Name: CentralAir, dtype: int64
SBrkr 1334
FuseA 94
FuseF 27
FuseP 3
Mix 1
Name: Electrical, dtype: int64
TA 735
Gd 586
Ex 100
Fa 39
Name: KitchenQual, dtype: int64
Typ 1360
Min2 34
Min1 31
Mod 15
Maj1 14
Maj2 5
Sev 1
Name: Functional, dtype: int64
Gd 380
TA 313
Fa 33
Ex 24
Po 20
Name: FireplaceQu, dtype: int64
Attchd 870
Detchd 387
BuiltIn 88
Basment 19
CarPort 9
2Types 6
Name: GarageType, dtype: int64
Unf 605
RFn 422
Fin 352
Name: GarageFinish, dtype: int64
TA 1311
Fa 48
Gd 14
Ex 3
Po 3
Name: GarageQual, dtype: int64
TA 1326
Fa 35
Gd 9
Po 7
Ex 2
Name: GarageCond, dtype: int64
Y 1340
N 90
P 30
Name: PavedDrive, dtype: int64
Gd 3
Fa 2
Ex 2
Name: PoolQC, dtype: int64
MnPrv 157
GdPrv 59
GdWo 54
MnWw 11
Name: Fence, dtype: int64
Shed 49
Gar2 2
Othr 2
TenC 1
Name: MiscFeature, dtype: int64
WD 1267
New 122
COD 43
ConLD 9
ConLI 5
ConLw 5
CWD 4
Oth 3
Con 2
Name: SaleType, dtype: int64
Normal 1198
Partial 125
Abnorml 101
Family 20
Alloca 12
AdjLand 4
Name: SaleCondition, dtype: int64 </code>
</pre>
</div>
<p>Great, now we know all of our object columns contain categories. In reality, this is rarely the case and you would have to do additional cleaning steps.</p>
<p>We should also note that some of these categories are ordered, such as ExterQual and ExterCond.</p>
<p>Also, you may have a dataset with thousands of features, so it is infeasible to look through all the categories like we did. In this case you can look at the number of unique values for each feature. Features with many unique values might be numerical values that weren’t properly encoded or free form text, which would have to be dealt with otherwise.</p>
<p>Next thing we want to do is deal with null values. Let’s see which columns have null values by showing the proportion of values in each column that are null.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="p">(</span><span class="n">df</span><span class="p">.</span><span class="n">isnull</span><span class="p">().</span><span class="nb">sum</span><span class="p">()</span><span class="o">/</span><span class="nb">len</span><span class="p">(</span><span class="n">df</span><span class="p">)).</span><span class="n">to_frame</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">'perc_null'</span><span class="p">)</span>
<span class="n">x</span><span class="p">[</span><span class="s">'types'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">dtypes</span>
<span class="n">x</span><span class="p">[</span><span class="n">x</span><span class="p">.</span><span class="n">perc_null</span><span class="o">></span><span class="mi">0</span><span class="p">].</span><span class="n">sort_values</span><span class="p">(</span><span class="s">'perc_null'</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</code></pre></div></div>
<div style="overflow-y:auto; height: 300px;">
<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>perc_null</th>
<th>types</th>
</tr>
</thead>
<tbody>
<tr>
<th>PoolQC</th>
<td>0.995205</td>
<td>object</td>
</tr>
<tr>
<th>MiscFeature</th>
<td>0.963014</td>
<td>object</td>
</tr>
<tr>
<th>Alley</th>
<td>0.937671</td>
<td>object</td>
</tr>
<tr>
<th>Fence</th>
<td>0.807534</td>
<td>object</td>
</tr>
<tr>
<th>FireplaceQu</th>
<td>0.472603</td>
<td>object</td>
</tr>
<tr>
<th>LotFrontage</th>
<td>0.177397</td>
<td>float64</td>
</tr>
<tr>
<th>GarageType</th>
<td>0.055479</td>
<td>object</td>
</tr>
<tr>
<th>GarageYrBlt</th>
<td>0.055479</td>
<td>float64</td>
</tr>
<tr>
<th>GarageFinish</th>
<td>0.055479</td>
<td>object</td>
</tr>
<tr>
<th>GarageQual</th>
<td>0.055479</td>
<td>object</td>
</tr>
<tr>
<th>GarageCond</th>
<td>0.055479</td>
<td>object</td>
</tr>
<tr>
<th>BsmtExposure</th>
<td>0.026027</td>
<td>object</td>
</tr>
<tr>
<th>BsmtFinType2</th>
<td>0.026027</td>
<td>object</td>
</tr>
<tr>
<th>BsmtFinType1</th>
<td>0.025342</td>
<td>object</td>
</tr>
<tr>
<th>BsmtCond</th>
<td>0.025342</td>
<td>object</td>
</tr>
<tr>
<th>BsmtQual</th>
<td>0.025342</td>
<td>object</td>
</tr>
<tr>
<th>MasVnrArea</th>
<td>0.005479</td>
<td>float64</td>
</tr>
<tr>
<th>MasVnrType</th>
<td>0.005479</td>
<td>object</td>
</tr>
<tr>
<th>Electrical</th>
<td>0.000685</td>
<td>object</td>
</tr>
</tbody>
</table>
</div>
<p>For the categorical variables, we will simply add a null category, when we turn them into categorical variables, pandas will automatically create a nan category if needed.</p>
<p>Dealing with nans (not a numbers) in numerical columns is more challenging. You typically want to replace the nans with a default value. Is there a reasonable default for this column? Does 0 make sense? What about the min/max/median? There is much discussion about this on the web.</p>
<p>Here, PoolQC and MasVnrArea are null when the house does not have a pool, so it makes sense to fill in 0 for these columns. For LotFrontage and GarageYrBuilt, we use the median. For the latter two, the missing information may have some pattern that helps us predict the price, so we will create an indicator column that tells us whether the column was null or not. This could be useful if, for example, all houses without a LotFrontage had a very small Lot, so they have a lower cost, so the indicator would help our model learn that this is the case.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df</span><span class="p">.</span><span class="n">PoolQC</span><span class="p">.</span><span class="n">fillna</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">df</span><span class="p">.</span><span class="n">MasVnrArea</span><span class="p">.</span><span class="n">fillna</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">fill_nulls</span><span class="p">(</span><span class="n">col</span><span class="p">,</span> <span class="n">filler</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">nanmedian</span><span class="p">):</span>
<span class="n">df</span><span class="p">[</span><span class="sa">f</span><span class="s">'</span><span class="si">{</span><span class="n">col</span><span class="si">}</span><span class="s">_null'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">df</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="n">col</span><span class="p">].</span><span class="n">isnull</span><span class="p">(),</span> <span class="sa">f</span><span class="s">'</span><span class="si">{</span><span class="n">col</span><span class="si">}</span><span class="s">_null'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">df</span><span class="p">[</span><span class="n">col</span><span class="p">].</span><span class="n">fillna</span><span class="p">(</span><span class="n">filler</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="n">col</span><span class="p">]),</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">fill_nulls</span><span class="p">(</span><span class="s">'LotFrontage'</span><span class="p">)</span>
<span class="n">fill_nulls</span><span class="p">(</span><span class="s">'GarageYrBlt'</span><span class="p">)</span>
</code></pre></div></div>
<p>Now, the “object” dtype columns are ready to be turned into actual categories. You can read more about the “category” dtype on the <a href="https://pandas.pydata.org/pandas-docs/version/0.24.2/reference/api/pandas.Categorical.html">pandas documentation page</a>. Essentially, it changes all the values from strings to numbers, so our model can use them.</p>
<p>For a vast majority of machine learning model types, we would need to do one additional step and “one-hot encode” these categorical variables. Since we are using a tree-based model, we will not need to do this, so we will not cover it.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">df</span><span class="p">.</span><span class="n">columns</span><span class="p">[</span><span class="n">df</span><span class="p">.</span><span class="n">dtypes</span><span class="o">==</span><span class="s">'object'</span><span class="p">]:</span>
<span class="n">df</span><span class="p">[</span><span class="n">col</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">col</span><span class="p">].</span><span class="n">astype</span><span class="p">(</span><span class="s">'category'</span><span class="p">)</span>
</code></pre></div></div>
<p>We noted above that some of the categorical features were ordered. We will encode two of them as ordered categorical columns, but leave the rest as an exercise.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pandas.api.types</span> <span class="kn">import</span> <span class="n">CategoricalDtype</span>
<span class="n">order</span> <span class="o">=</span> <span class="p">[</span><span class="s">'Po'</span><span class="p">,</span> <span class="s">'Fa'</span><span class="p">,</span> <span class="s">'TA'</span><span class="p">,</span> <span class="s">'Gd'</span><span class="p">,</span> <span class="s">'Ex'</span><span class="p">]</span>
<span class="n">cat_type</span> <span class="o">=</span> <span class="n">CategoricalDtype</span><span class="p">(</span><span class="n">categories</span><span class="o">=</span><span class="n">order</span><span class="p">,</span> <span class="n">ordered</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s">'ExterQual'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">'ExterQual'</span><span class="p">].</span><span class="n">astype</span><span class="p">(</span><span class="n">cat_type</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s">'ExterCond'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">'ExterCond'</span><span class="p">].</span><span class="n">astype</span><span class="p">(</span><span class="n">cat_type</span><span class="p">)</span>
</code></pre></div></div>
<p>We can take a look at some of the category codes along with the original strings:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="s">'ExterQual'</span><span class="p">][:</span><span class="mi">10</span><span class="p">].</span><span class="n">cat</span><span class="p">.</span><span class="n">codes</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="s">'ExterQual'</span><span class="p">][:</span><span class="mi">10</span><span class="p">])</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">0 3
1 2
2 3
3 2
4 3
5 2
6 3
7 2
8 2
9 2
dtype: int8
0 Gd
1 TA
2 Gd
3 TA
4 Gd
5 TA
6 Gd
7 TA
8 TA
9 TA
Name: ExterQual, dtype: category
Categories (5, object): [Po < Fa < TA < Gd < Ex]</code>
</pre>
</div>
<p>So far, we’ve done some basic data transformations so the data can be fed into our model. We did no feature engineering or data exploration. Your dataset could have thousands of dimensions, so it is infeasible to extensively explore the data before modelling. Our approach will be to let the model tell us what’s important and what’s not so we can focus our effots appropriately.</p>
<h2 id="modeling">Modeling</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sklearn.tree</span> <span class="kn">import</span> <span class="n">DecisionTreeRegressor</span>
<span class="kn">from</span> <span class="nn">sklearn.ensemble</span> <span class="kn">import</span> <span class="n">RandomForestRegressor</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
</code></pre></div></div>
<p>Our goal is to predict the price of the houses given the rest of the information. We start by splitting our dataframe into our features (our model inputs) and our target (the price we are trying to predict).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df_y</span><span class="p">,</span> <span class="n">df_x</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">'SalePrice'</span><span class="p">],</span> <span class="n">df</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="s">'SalePrice'</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># same as axis='columns'
</span></code></pre></div></div>
<p>Scikit-learn expects numerical values for all the columns, but our categorical variables contain text. We will replace the text with their numeric category number:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">df_x</span><span class="p">.</span><span class="n">columns</span><span class="p">[</span><span class="n">df_x</span><span class="p">.</span><span class="n">dtypes</span><span class="o">==</span><span class="s">'category'</span><span class="p">]:</span>
<span class="n">df_x</span><span class="p">[</span><span class="n">col</span><span class="p">]</span> <span class="o">=</span> <span class="n">df_x</span><span class="p">[</span><span class="n">col</span><span class="p">].</span><span class="n">cat</span><span class="p">.</span><span class="n">codes</span>
</code></pre></div></div>
<p>In machine learning, you typically split your data into a training, validation, and test set. You train your model on the training set, then evaluate the performance on the validation set. You use this validation set to tune hyperparameters (explained later). After selecting your model, you use the test set as one final check to make sure your model generalizes well (and you didn’t just “overfit” to your validation set).</p>
<p>These concepts will be explained in more detail below. We split our data into just training and validation for simplicity, as we won’t be doing any rigorous model selection.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">X_train</span><span class="p">,</span> <span class="n">X_valid</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_valid</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span>
<span class="n">df_x</span><span class="p">,</span> <span class="n">df_y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span>
</code></pre></div></div>
<p>Let’s create some convenience functions to evaluate our model. Metric selection will not be discussed during this workshop. Here, we use the root mean squared error as our metric. Mean squared error is a common metric used for regression problems, and root mean squared error is nice in that it is in the same units as your original output.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">rmse</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="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">(((</span><span class="n">x</span><span class="o">-</span><span class="n">y</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)))</span>
<span class="k">def</span> <span class="nf">print_score</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">X_t</span><span class="o">=</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_t</span><span class="o">=</span><span class="n">y_train</span><span class="p">,</span>
<span class="n">X_v</span><span class="o">=</span><span class="n">X_valid</span><span class="p">,</span> <span class="n">y_v</span><span class="o">=</span><span class="n">y_valid</span><span class="p">):</span>
<span class="n">scores</span> <span class="o">=</span> <span class="p">[</span><span class="n">rmse</span><span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_t</span><span class="p">),</span> <span class="n">y_t</span><span class="p">),</span>
<span class="n">rmse</span><span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_v</span><span class="p">),</span> <span class="n">y_v</span><span class="p">),</span>
<span class="n">model</span><span class="p">.</span><span class="n">score</span><span class="p">(</span><span class="n">X_t</span><span class="p">,</span> <span class="n">y_t</span><span class="p">),</span>
<span class="n">model</span><span class="p">.</span><span class="n">score</span><span class="p">(</span><span class="n">X_v</span><span class="p">,</span> <span class="n">y_v</span><span class="p">)]</span>
<span class="n">labels</span> <span class="o">=</span> <span class="p">[</span><span class="s">'Train RMSE'</span><span class="p">,</span> <span class="s">'Valid RMSE'</span><span class="p">,</span> <span class="s">'Train R^2'</span><span class="p">,</span> <span class="s">'Valid R^2'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">t</span><span class="p">,</span> <span class="n">s</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">scores</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'</span><span class="si">{</span><span class="n">t</span><span class="si">}</span><span class="s">: </span><span class="si">{</span><span class="n">s</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
</code></pre></div></div>
<p>Time to fit our first model: a DecisionTree! It’s as easy as:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tree</span> <span class="o">=</span> <span class="n">DecisionTreeRegressor</span><span class="p">(</span><span class="n">min_samples_leaf</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span>
<span class="n">tree</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
</code></pre></div></div>
<p>We used the <code class="language-plaintext highlighter-rouge">min_samples_leaf</code> argument to limit the size of the tree so we can visualize it below:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sklearn.externals.six</span> <span class="kn">import</span> <span class="n">StringIO</span>
<span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">Image</span>
<span class="kn">from</span> <span class="nn">sklearn.tree</span> <span class="kn">import</span> <span class="n">export_graphviz</span>
<span class="kn">import</span> <span class="nn">pydotplus</span>
<span class="n">dot_data</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
<span class="n">g</span> <span class="o">=</span> <span class="n">export_graphviz</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">out_file</span><span class="o">=</span><span class="n">dot_data</span><span class="p">,</span>
<span class="n">filled</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">rounded</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">special_characters</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">feature_names</span><span class="o">=</span><span class="n">X_train</span><span class="p">.</span><span class="n">columns</span><span class="p">)</span>
<span class="n">graph</span> <span class="o">=</span> <span class="n">pydotplus</span><span class="p">.</span><span class="n">graph_from_dot_data</span><span class="p">(</span><span class="n">dot_data</span><span class="p">.</span><span class="n">getvalue</span><span class="p">())</span>
<span class="n">Image</span><span class="p">(</span><span class="n">graph</span><span class="p">.</span><span class="n">create_png</span><span class="p">())</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_36_1.png#center" alt="png" /></p>
<p>Given the features, the decision tree works as follows: we start at the root and look at the feature in question. If the condition at the top is True, we follow the True branch, otherwise we follow the False branch. This process continues until we reach a leaf. The value at the leaf is our prediction.</p>
<p>The tree is trained as follows. We take the data, and we look at all the features and values of these features to find the best split. The best split is the one such that our evaluation metric (mean squared error) is minimized by the split. In other words, if this split is used, the mean squared error of the model that comes from this split is minimized. The samples represents the number of samples of data that are in the subtree (due to the splits). The value is the mean target value of all the samples in that subtree. Then we repeat until each leaf only contains one sample (usually).</p>
<p>Let’s build a full decision tree and evaluate its performance:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">DecisionTreeRegressor</span><span class="p">()</span>
<span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">print_score</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">Train RMSE: 0.0
Valid RMSE: 43111.0938316298
Train R^2: 1.0
Valid R^2: 0.7576939544477124</code>
</pre>
</div>
<p>We see the Decision Tree has overfit. So, we introduce Random Forests:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">RandomForestRegressor</span><span class="p">(</span><span class="n">n_estimators</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span>
<span class="n">n_jobs</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">print_score</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">Train RMSE: 11972.136923038881
Valid RMSE: 29315.10749027229
Train R^2: 0.9759693433070632
Valid R^2: 0.8879610196550729</code>
</pre>
</div>
<p>There are a few key hyperparameters to tune (shown below):</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">RandomForestRegressor</span><span class="p">(</span><span class="n">n_estimators</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
<span class="n">n_jobs</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
<span class="n">min_samples_leaf</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="n">max_features</span><span class="o">=</span><span class="mf">0.8</span><span class="p">)</span> <span class="c1">#'sqrt', 'log2'
</span><span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">print_score</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">Train RMSE: 11464.59450285856
Valid RMSE: 29159.246751559134
Train R^2: 0.9779636487670959
Valid R^2: 0.889149216323862</code>
</pre>
</div>
<h2 id="feature-importances">Feature Importances</h2>
<p>Now that we have a model with reasonable performance, we can use it to understand our dataset (and use that to improve the model). The first is looking at feature importance.</p>
<p>To calculate feature x’s importance, we first shuffle x column. Now, the feature is uncorrelated with the target. Next, we evaluate the model’s performance on the training set and see how much it has decreased compared to when the feature was unshuffled. The higher this value, the more important the feature is.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># properties with an underscore are available after you fit the model
</span><span class="n">fi</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">feature_importances_</span><span class="p">,</span>
<span class="n">index</span> <span class="o">=</span> <span class="n">X_train</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span>
<span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s">'importance'</span><span class="p">])</span>
<span class="n">fi</span> <span class="o">=</span> <span class="n">fi</span><span class="p">.</span><span class="n">sort_values</span><span class="p">(</span><span class="s">'importance'</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">fi</span><span class="p">[:</span><span class="mi">30</span><span class="p">].</span><span class="n">plot</span><span class="p">.</span><span class="n">barh</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">7</span><span class="p">))</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_45_1.png#center" alt="png" /></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fi</span><span class="p">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'YearRemodAdd'</span><span class="p">]</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">importance 0.00591
Name: YearRemodAdd, dtype: float64</code>
</pre>
</div>
<p>These importances tell you where to focus your attention on your dataset. Your data may have thousands of features, so having a way to narrow your investigation scope is very helpful.</p>
<p>Here are a few things to think about:</p>
<ul>
<li>Which features are the most important? This is a good opportunity to do some feature engineering. For example, if a date turned out to be an important feature, you may want to split this up into more granular features, such as splitting up the day/month/year, day of week, adding season, etc.</li>
<li>Which features are less important? Can we make them more useful through feature engineering?</li>
<li>Do the important features make sense? For example, suppose the data had an ID number that was assigned randomly, but turned out to be important. This is suspicious and you should look into the data and see why this is the case.</li>
<li>Are there are any features you expected to be important but aren’t? This could indicate some data cleaning work you missed. If not, this is useful to build intuition about your dat.</li>
<li>If there are highly correlated features, which of the correlated features are important? How does removing the less important feature affect the model performance?</li>
<li>And many more…</li>
</ul>
<p>Let’s try keeping only the important features and seeing how the model performs:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">X_train_new</span> <span class="o">=</span> <span class="n">X_train</span><span class="p">[</span><span class="n">fi</span><span class="p">[</span><span class="n">fi</span><span class="p">[</span><span class="s">'importance'</span><span class="p">]</span> <span class="o">></span> <span class="mf">0.005</span><span class="p">].</span><span class="n">index</span><span class="p">]</span>
<span class="n">X_valid_new</span> <span class="o">=</span> <span class="n">X_valid</span><span class="p">[</span><span class="n">fi</span><span class="p">[</span><span class="n">fi</span><span class="p">[</span><span class="s">'importance'</span><span class="p">]</span> <span class="o">></span> <span class="mf">0.005</span><span class="p">].</span><span class="n">index</span><span class="p">]</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">X_train</span><span class="p">.</span><span class="n">shape</span> <span class="c1"># see how many features are left
</span></code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">(1168, 82)</code>
</pre>
</div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model_new</span> <span class="o">=</span> <span class="n">RandomForestRegressor</span><span class="p">(</span><span class="n">n_estimators</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span>
<span class="n">n_jobs</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
<span class="n">oob_score</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">min_samples_leaf</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span>
<span class="n">max_features</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">model_new</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train_new</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">print_score</span><span class="p">(</span><span class="n">model_new</span><span class="p">,</span> <span class="n">X_t</span><span class="o">=</span><span class="n">X_train_new</span><span class="p">,</span> <span class="n">X_v</span><span class="o">=</span><span class="n">X_valid_new</span><span class="p">)</span>
</code></pre></div></div>
<div class="output_block">
<pre>
<code class="codeblock">Train RMSE: 17820.096007344346
Valid RMSE: 29815.94532060853
Train R^2: 0.9467594702883222
Valid R^2: 0.8841000276456914</code>
</pre>
</div>
<p>We can compare the feature importances from the model trained with all the features vs the model with just some of the features.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fi2</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">model_new</span><span class="p">.</span><span class="n">feature_importances_</span><span class="p">,</span>
<span class="n">index</span> <span class="o">=</span> <span class="n">X_train_new</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span>
<span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s">'importance'</span><span class="p">]).</span><span class="n">sort_values</span><span class="p">(</span><span class="s">'importance'</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">25</span><span class="p">,</span><span class="mi">8</span><span class="p">))</span>
<span class="n">fi</span><span class="p">[:</span><span class="mi">16</span><span class="p">].</span><span class="n">plot</span><span class="p">.</span><span class="n">barh</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">title</span><span class="o">=</span><span class="s">'Nice'</span><span class="p">)</span>
<span class="n">fi2</span><span class="p">.</span><span class="n">plot</span><span class="p">.</span><span class="n">barh</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_52_1.png#center" alt="png" /></p>
<h2 id="identifying-correlated-features">Identifying Correlated Features</h2>
<p>Identifying and resolving correlated features can sometimes improve your model in a few ways:</p>
<ul>
<li>Decreases the dimensionality of your data</li>
<li>Can reduce overfitting</li>
<li>Prevents the model from learning unintended biases</li>
<li>Makes the model more interpretable (treeinterpeter/partial depencence plots will be more accurate)</li>
<li>And more.</li>
</ul>
<p>For many model types, you would look at normal (linear) correlation, but a random forest is not affected by just linear correlation. Since the trees simply split the data at some point, just the <strong>rank</strong> of the feature matters.</p>
<p>Consider you sort the data by a feature. The rank is the position of the example in the sorted dataset. Below, we identify rank correlations.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">scipy.cluster</span> <span class="kn">import</span> <span class="n">hierarchy</span> <span class="k">as</span> <span class="n">hc</span>
<span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">stats</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">df2</span> <span class="o">=</span> <span class="n">X_train_new</span><span class="p">[</span>
<span class="n">X_train_new</span><span class="p">.</span><span class="n">columns</span><span class="p">[</span><span class="n">X_train_new</span><span class="p">.</span><span class="n">dtypes</span> <span class="o">!=</span> <span class="s">'category'</span><span class="p">]</span>
<span class="p">]</span>
<span class="n">corr</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">round</span><span class="p">(</span><span class="n">stats</span><span class="p">.</span><span class="n">spearmanr</span><span class="p">(</span><span class="n">df2</span><span class="p">).</span><span class="n">correlation</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</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="mi">8</span><span class="p">))</span>
<span class="n">g</span> <span class="o">=</span> <span class="n">sns</span><span class="p">.</span><span class="n">heatmap</span><span class="p">(</span><span class="n">corr</span><span class="p">,</span> <span class="n">ax</span><span class="o">=</span><span class="n">ax</span><span class="p">)</span>
<span class="n">g</span><span class="p">.</span><span class="n">set_yticklabels</span><span class="p">(</span><span class="n">df2</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="n">g</span><span class="p">.</span><span class="n">set_xticklabels</span><span class="p">(</span><span class="n">df2</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">90</span><span class="p">)</span>
<span class="bp">None</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_57_0.png#center" alt="png" /></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">corr_condensed</span> <span class="o">=</span> <span class="n">hc</span><span class="p">.</span><span class="n">distance</span><span class="p">.</span><span class="n">squareform</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">corr</span><span class="p">)</span>
<span class="n">z</span> <span class="o">=</span> <span class="n">hc</span><span class="p">.</span><span class="n">linkage</span><span class="p">(</span><span class="n">corr_condensed</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s">'average'</span><span class="p">)</span>
<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</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">16</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
<span class="n">dendrogram</span> <span class="o">=</span> <span class="n">hc</span><span class="p">.</span><span class="n">dendrogram</span><span class="p">(</span><span class="n">z</span><span class="p">,</span> <span class="n">labels</span><span class="o">=</span><span class="n">df2</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span> <span class="n">orientation</span><span class="o">=</span><span class="s">'left'</span><span class="p">,</span>
<span class="n">leaf_font_size</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_58_0.png#center" alt="png" /></p>
<h2 id="tree-interpreter">Tree Interpreter</h2>
<p>Tree interpreter is a great way to understand the individual predictions. Recall for a Decision Tree, at each node, the model makes a “decision” based on a condition on a feature to follow the left child or the right child. Each node contains the average target value for the subset of data that satisfies the condition. The tree interpreter measures how much the average changes for each of these decisions for each feature (averaged across all trees). We call this average change the contribution of the feature.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">treeinterpreter</span> <span class="kn">import</span> <span class="n">treeinterpreter</span> <span class="k">as</span> <span class="n">ti</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">X_valid</span><span class="p">.</span><span class="n">values</span><span class="p">[</span><span class="bp">None</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span>
<span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">contributions</span> <span class="o">=</span> <span class="n">ti</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="n">ti_df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span><span class="p">({</span>
<span class="s">'feature'</span><span class="p">:</span> <span class="n">X_valid</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span>
<span class="s">'value'</span><span class="p">:</span> <span class="n">X_valid</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="s">'contributions'</span><span class="p">:</span> <span class="n">contributions</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="p">})</span>
<span class="n">show_all</span><span class="p">(</span><span class="n">ti_df</span><span class="p">.</span><span class="n">sort_values</span><span class="p">(</span><span class="s">'contributions'</span><span class="p">))</span>
</code></pre></div></div>
<div style="overflow-y:auto; height: 300px;">
<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>feature</th>
<th>value</th>
<th>contributions</th>
</tr>
</thead>
<tbody>
<tr>
<th>OverallQual</th>
<td>OverallQual</td>
<td>6.0</td>
<td>-23204.618284</td>
</tr>
<tr>
<th>GrLivArea</th>
<td>GrLivArea</td>
<td>1068.0</td>
<td>-18869.146520</td>
</tr>
<tr>
<th>GarageArea</th>
<td>GarageArea</td>
<td>264.0</td>
<td>-6130.961614</td>
</tr>
<tr>
<th>GarageCars</th>
<td>GarageCars</td>
<td>1.0</td>
<td>-4230.235767</td>
</tr>
<tr>
<th>ExterQual</th>
<td>ExterQual</td>
<td>2.0</td>
<td>-3690.661634</td>
</tr>
<tr>
<th>YearBuilt</th>
<td>YearBuilt</td>
<td>1963.0</td>
<td>-1606.690435</td>
</tr>
<tr>
<th>FullBath</th>
<td>FullBath</td>
<td>1.0</td>
<td>-1549.810925</td>
</tr>
<tr>
<th>MoSold</th>
<td>MoSold</td>
<td>2.0</td>
<td>-1044.108978</td>
</tr>
<tr>
<th>GarageYrBlt</th>
<td>GarageYrBlt</td>
<td>1963.0</td>
<td>-839.353054</td>
</tr>
<tr>
<th>1stFlrSF</th>
<td>1stFlrSF</td>
<td>1068.0</td>
<td>-761.773371</td>
</tr>
<tr>
<th>FireplaceQu</th>
<td>FireplaceQu</td>
<td>-1.0</td>
<td>-435.448301</td>
</tr>
<tr>
<th>2ndFlrSF</th>
<td>2ndFlrSF</td>
<td>0.0</td>
<td>-353.114027</td>
</tr>
<tr>
<th>KitchenQual</th>
<td>KitchenQual</td>
<td>3.0</td>
<td>-274.866357</td>
</tr>
<tr>
<th>YrSold</th>
<td>YrSold</td>
<td>2006.0</td>
<td>-260.455148</td>
</tr>
<tr>
<th>HouseStyle</th>
<td>HouseStyle</td>
<td>2.0</td>
<td>-241.007907</td>
</tr>
<tr>
<th>HeatingQC</th>
<td>HeatingQC</td>
<td>4.0</td>
<td>-224.041546</td>
</tr>
<tr>
<th>MasVnrArea</th>
<td>MasVnrArea</td>
<td>0.0</td>
<td>-184.002489</td>
</tr>
<tr>
<th>Id</th>
<td>Id</td>
<td>893.0</td>
<td>-171.481627</td>
</tr>
<tr>
<th>Fireplaces</th>
<td>Fireplaces</td>
<td>0.0</td>
<td>-142.288747</td>
</tr>
<tr>
<th>BsmtFullBath</th>
<td>BsmtFullBath</td>
<td>0.0</td>
<td>-139.435641</td>
</tr>
<tr>
<th>BsmtFinSF2</th>
<td>BsmtFinSF2</td>
<td>0.0</td>
<td>-132.122053</td>
</tr>
<tr>
<th>BsmtExposure</th>
<td>BsmtExposure</td>
<td>3.0</td>
<td>-116.156015</td>
</tr>
<tr>
<th>BsmtQual</th>
<td>BsmtQual</td>
<td>3.0</td>
<td>-111.225296</td>
</tr>
<tr>
<th>Neighborhood</th>
<td>Neighborhood</td>
<td>19.0</td>
<td>-76.460459</td>
</tr>
<tr>
<th>ExterCond</th>
<td>ExterCond</td>
<td>2.0</td>
<td>-58.762708</td>
</tr>
<tr>
<th>HalfBath</th>
<td>HalfBath</td>
<td>0.0</td>
<td>-38.991079</td>
</tr>
<tr>
<th>SaleType</th>
<td>SaleType</td>
<td>8.0</td>
<td>-27.675000</td>
</tr>
<tr>
<th>LotFrontage_null</th>
<td>LotFrontage_null</td>
<td>0.0</td>
<td>-21.285714</td>
</tr>
<tr>
<th>ScreenPorch</th>
<td>ScreenPorch</td>
<td>0.0</td>
<td>-17.295352</td>
</tr>
<tr>
<th>MiscFeature</th>
<td>MiscFeature</td>
<td>-1.0</td>
<td>-17.083333</td>
</tr>
<tr>
<th>GarageFinish</th>
<td>GarageFinish</td>
<td>1.0</td>
<td>-0.033333</td>
</tr>
<tr>
<th>KitchenAbvGr</th>
<td>KitchenAbvGr</td>
<td>1.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Electrical</th>
<td>Electrical</td>
<td>4.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>LowQualFinSF</th>
<td>LowQualFinSF</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Utilities</th>
<td>Utilities</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>LotShape</th>
<td>LotShape</td>
<td>3.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>LandSlope</th>
<td>LandSlope</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Heating</th>
<td>Heating</td>
<td>1.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>GarageYrBlt_null</th>
<td>GarageYrBlt_null</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Functional</th>
<td>Functional</td>
<td>6.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>BldgType</th>
<td>BldgType</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Street</th>
<td>Street</td>
<td>1.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>3SsnPorch</th>
<td>3SsnPorch</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>PoolArea</th>
<td>PoolArea</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>PoolQC</th>
<td>PoolQC</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>RoofMatl</th>
<td>RoofMatl</td>
<td>1.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>MiscVal</th>
<td>MiscVal</td>
<td>0.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Condition2</th>
<td>Condition2</td>
<td>2.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>TotRmsAbvGrd</th>
<td>TotRmsAbvGrd</td>
<td>6.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>Alley</th>
<td>Alley</td>
<td>-1.0</td>
<td>0.000000</td>
</tr>
<tr>
<th>BsmtHalfBath</th>
<td>BsmtHalfBath</td>
<td>1.0</td>
<td>4.666667</td>
</tr>
<tr>
<th>LandContour</th>
<td>LandContour</td>
<td>3.0</td>
<td>19.390152</td>
</tr>
<tr>
<th>MasVnrType</th>
<td>MasVnrType</td>
<td>2.0</td>
<td>20.747510</td>
</tr>
<tr>
<th>Condition1</th>
<td>Condition1</td>
<td>2.0</td>
<td>27.096890</td>
</tr>
<tr>
<th>Foundation</th>
<td>Foundation</td>
<td>1.0</td>
<td>27.947817</td>
</tr>
<tr>
<th>EnclosedPorch</th>
<td>EnclosedPorch</td>
<td>0.0</td>
<td>28.570496</td>
</tr>
<tr>
<th>PavedDrive</th>
<td>PavedDrive</td>
<td>2.0</td>
<td>40.605275</td>
</tr>
<tr>
<th>Exterior1st</th>
<td>Exterior1st</td>
<td>6.0</td>
<td>50.324136</td>
</tr>
<tr>
<th>LotConfig</th>
<td>LotConfig</td>
<td>4.0</td>
<td>56.750000</td>
</tr>
<tr>
<th>BsmtFinType2</th>
<td>BsmtFinType2</td>
<td>5.0</td>
<td>73.333333</td>
</tr>
<tr>
<th>MSSubClass</th>
<td>MSSubClass</td>
<td>20.0</td>
<td>80.537781</td>
</tr>
<tr>
<th>OpenPorchSF</th>
<td>OpenPorchSF</td>
<td>0.0</td>
<td>98.498287</td>
</tr>
<tr>
<th>Exterior2nd</th>
<td>Exterior2nd</td>
<td>6.0</td>
<td>99.801761</td>
</tr>
<tr>
<th>BsmtFinType1</th>
<td>BsmtFinType1</td>
<td>2.0</td>
<td>151.642921</td>
</tr>
<tr>
<th>RoofStyle</th>
<td>RoofStyle</td>
<td>3.0</td>
<td>153.249065</td>
</tr>
<tr>
<th>BedroomAbvGr</th>
<td>BedroomAbvGr</td>
<td>3.0</td>
<td>161.383636</td>
</tr>
<tr>
<th>BsmtCond</th>
<td>BsmtCond</td>
<td>3.0</td>
<td>255.793641</td>
</tr>
<tr>
<th>GarageCond</th>
<td>GarageCond</td>
<td>4.0</td>
<td>264.679058</td>
</tr>
<tr>
<th>Fence</th>
<td>Fence</td>
<td>2.0</td>
<td>321.183333</td>
</tr>
<tr>
<th>MSZoning</th>
<td>MSZoning</td>
<td>3.0</td>
<td>396.914474</td>
</tr>
<tr>
<th>BsmtFinSF1</th>
<td>BsmtFinSF1</td>
<td>663.0</td>
<td>449.878523</td>
</tr>
<tr>
<th>GarageQual</th>
<td>GarageQual</td>
<td>4.0</td>
<td>462.399980</td>
</tr>
<tr>
<th>WoodDeckSF</th>
<td>WoodDeckSF</td>
<td>192.0</td>
<td>487.761372</td>
</tr>
<tr>
<th>SaleCondition</th>
<td>SaleCondition</td>
<td>4.0</td>
<td>490.223394</td>
</tr>
<tr>
<th>CentralAir</th>
<td>CentralAir</td>
<td>1.0</td>
<td>533.540801</td>
</tr>
<tr>
<th>GarageType</th>
<td>GarageType</td>
<td>1.0</td>
<td>569.096237</td>
</tr>
<tr>
<th>BsmtUnfSF</th>
<td>BsmtUnfSF</td>
<td>396.0</td>
<td>601.818903</td>
</tr>
<tr>
<th>LotArea</th>
<td>LotArea</td>
<td>8414.0</td>
<td>982.527398</td>
</tr>
<tr>
<th>LotFrontage</th>
<td>LotFrontage</td>
<td>70.0</td>
<td>1255.136900</td>
</tr>
<tr>
<th>OverallCond</th>
<td>OverallCond</td>
<td>8.0</td>
<td>2634.189802</td>
</tr>
<tr>
<th>YearRemodAdd</th>
<td>YearRemodAdd</td>
<td>2003.0</td>
<td>2661.275923</td>
</tr>
<tr>
<th>TotalBsmtSF</th>
<td>TotalBsmtSF</td>
<td>1059.0</td>
<td>11313.187661</td>
</tr>
</tbody>
</table>
</div>
<h2 id="partial-dependence-plots">Partial Dependence Plots</h2>
<p>We will not cover Partial Dependence Plots in this workshop, but here is some code demonstrating how you can use them.</p>
<p>Partial dependence use the model and dataset as follows. It varies the value of the feature of interest while keeping the rest of the features the same. Then, it uses the model to make a prediction on this augmented data. This way, we can see the effect of that feature alone. This library finds clusters in the dataset predictions for you.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pdpbox</span> <span class="kn">import</span> <span class="n">pdp</span>
<span class="k">def</span> <span class="nf">plot_pdp</span><span class="p">(</span><span class="n">feat</span><span class="p">,</span> <span class="n">clusters</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">feat_name</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">feat_name</span> <span class="o">=</span> <span class="n">feat_name</span> <span class="ow">or</span> <span class="n">feat</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">pdp</span><span class="p">.</span><span class="n">pdp_isolate</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">X_train</span><span class="p">,</span> <span class="n">X_train</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span> <span class="n">feat</span><span class="p">)</span>
<span class="k">return</span> <span class="n">pdp</span><span class="p">.</span><span class="n">pdp_plot</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">feat_name</span><span class="p">,</span>
<span class="n">plot_lines</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">cluster</span><span class="o">=</span><span class="n">clusters</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">,</span>
<span class="n">n_cluster_centers</span><span class="o">=</span><span class="n">clusters</span><span class="p">)</span>
<span class="n">plot_pdp</span><span class="p">(</span><span class="s">'GrLivArea'</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_69_1.png#center" alt="png" /></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">plot_pdp</span><span class="p">(</span><span class="s">'OverallQual'</span><span class="p">,</span> <span class="n">clusters</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">()</span>
<span class="n">sns</span><span class="p">.</span><span class="n">regplot</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">df</span><span class="p">,</span> <span class="n">x</span><span class="o">=</span><span class="s">'OverallQual'</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="s">'SalePrice'</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_70_1.png#center" alt="png" /></p>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_70_2.png#center" alt="png" /></p>
<p>There seems to be an issue in the library related to plotting (or perhaps my code is wrong somehow), which is why I use a try-except block. Due to this issue, the axis are not shown.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">feats</span> <span class="o">=</span> <span class="p">[</span><span class="s">'OverallQual'</span><span class="p">,</span> <span class="s">'GrLivArea'</span><span class="p">]</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">pdp</span><span class="p">.</span><span class="n">pdp_interact</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">X_train</span><span class="p">,</span> <span class="n">X_train</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span> <span class="n">feats</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">pdp</span><span class="p">.</span><span class="n">pdp_interact_plot</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">feats</span><span class="p">)</span>
<span class="k">except</span> <span class="nb">TypeError</span><span class="p">:</span>
<span class="k">pass</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_72_0.png#center" alt="png" /></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">feats</span> <span class="o">=</span> <span class="p">[</span><span class="s">'OverallCond'</span><span class="p">,</span> <span class="s">'OverallQual'</span><span class="p">]</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">pdp</span><span class="p">.</span><span class="n">pdp_interact</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">X_train</span><span class="p">,</span> <span class="n">X_train</span><span class="p">.</span><span class="n">columns</span><span class="p">,</span> <span class="n">feats</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">pdp</span><span class="p">.</span><span class="n">pdp_interact_plot</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">feats</span><span class="p">)</span>
<span class="k">except</span> <span class="nb">TypeError</span><span class="p">:</span>
<span class="k">pass</span>
</code></pre></div></div>
<p><img src="/assets/images/posts/intro-to-random-forests/Random_Forests_Workshop_V2_73_0.png#center" alt="png" /></p>
<h2 id="standard-process-for-quick-rf-development">Standard Process for Quick RF Development:</h2>
<ol>
<li>Using scoring metric (provided or decided), create a scoring function (training + validation).</li>
<li>Create a validation set with same properties as test set.</li>
<li>Run a quick random forest on the data with minimal alterations.</li>
<li>Plot feature importance, plot the features, and learn about those features (domain knowledge).</li>
<li>Use a natural breakpoint to remove unimportant features then plot again.</li>
<li>Look at data carefully and encode important features better.</li>
<li>Using heirachical clustering to remove redundant features (scipy)</li>
<li>For interpretation, use partial dependence plots from PDP.</li>
<li>Use Tree Interpreter to explain individual predictions.</li>
</ol>Nicholas Vadivelunicholas.vadivelu@gmail.comThrough this workshop you will learn how to quickly model and understand datasets using scikit-learn. Topics will include a basic introduction to using decisions trees and random forests, understanding feature importance, identifying model weaknesses, explaining your model, and more.