<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rishabh Bhartiya</title>
    <description>The latest articles on DEV Community by Rishabh Bhartiya (@rishabhbhartiya).</description>
    <link>https://dev.to/rishabhbhartiya</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3855341%2Feb317c87-e5a3-419e-8eff-7aeb8675f5f7.png</url>
      <title>DEV Community: Rishabh Bhartiya</title>
      <link>https://dev.to/rishabhbhartiya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rishabhbhartiya"/>
    <language>en</language>
    <item>
      <title>Why Statistics Needs Animation — And How to Do It in Python</title>
      <dc:creator>Rishabh Bhartiya</dc:creator>
      <pubDate>Wed, 10 Jun 2026 04:16:22 +0000</pubDate>
      <link>https://dev.to/rishabhbhartiya/why-statistics-needs-animation-and-how-to-do-it-in-python-21ph</link>
      <guid>https://dev.to/rishabhbhartiya/why-statistics-needs-animation-and-how-to-do-it-in-python-21ph</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://medium.com/@rishabh.bhartiya.in/why-statistics-needs-animation-and-how-to-do-it-in-python-ec61893e875b" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Static diagrams freeze what statistics is meant to show in motion. Here’s how one Python library is closing the gap.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“&lt;strong&gt;A&lt;/strong&gt;sk a statistics student what a confidence interval means. Most can recite the definition. Ask them to feel it — to have immediate intuitive grasp of why it shrinks as sample size grows — almost none can.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn’t a failure of intelligence. It’s a failure of medium.&lt;/p&gt;

&lt;p&gt;Statistics describes processes that unfold over time: samples being drawn, distributions emerging, parameters shifting, evidence accumulating. Yet we almost universally teach it through static images and symbolic notation. The normal distribution on a whiteboard is frozen. The actual thing it describes — the shape that emerges from infinite repeated measurement — is alive.&lt;/p&gt;

&lt;p&gt;The gap between the symbol and the intuition is where most statistical confusion lives. Animation closes that gap. And with the right tooling, building statistical animations in Python is now surprisingly straightforward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Manim — and why it needed a statistics layer&lt;/strong&gt;&lt;br&gt;
Manim Community is the open-source mathematical animation engine behind much of 3Blue1Brown’s visual mathematics work. It renders at publication quality and operates on a clean object model where every visual element is a mobject with position, color, and transform behaviour.&lt;/p&gt;

&lt;p&gt;The problem for statistics specifically: Manim operates at a very low level of abstraction. Want to animate a normal distribution with a shadeable region? You’re writing curve geometry and area calculation code before you’ve touched a single line of statistics.&lt;/p&gt;

&lt;p&gt;Learn about Medium’s values&lt;br&gt;
statanim raises that abstraction level specifically for statistics. It provides statistical objects and animations as first-class Manim extensions — distributions, inference visualisations, regression surfaces, and physical probability props — all built on top of Manim Community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;br&gt;
You’ll need Python 3.10+, Manim Community, a LaTeX distribution, and statanim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Install Manim
pip install manim

# LaTeX (pick your platform)
# macOS:   brew install mactex-no-gui
# Ubuntu:  sudo apt-get install texlive-full
# Windows: install MiKTeX from https://miktex.org/
# Install statanim
pip install statanim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify your setup with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from manim import *
from statanim.distributions.normal3d import NormalCurve3D
from statanim.props.card import Card3D
from statanim.core.colors import DARK_THEME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that imports cleanly, you’re ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 1: Animating Distributions&lt;/strong&gt;&lt;br&gt;
The normal distribution — parameter sweep&lt;br&gt;
The most common introductory statistics animation: a normal distribution whose sigma changes, showing how spread and peak height relate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from manim import *
from statanim.distributions.normal3d import NormalCurve3D

class NormalSweep(Scene):
    def construct(self):
        axes = Axes(
            x_range=[-5, 5, 1],
            y_range=[0, 0.9, 0.1],
            x_length=10,
            y_length=5
        )
        self.play(Create(axes))
        curve = NormalCurve3D(mu=0, sigma=1, axes=axes)
        self.play(Create(curve))
        self.wait(1)
        # shade one-sigma region
        self.play(curve.shade_region(x_min=-1, x_max=1))
        self.wait(1)
        # morph to sigma = 2
        curve2 = NormalCurve3D(mu=0, sigma=2, axes=axes)
        self.play(Transform(curve, curve2))
        self.wait(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it with manim -pql normal_sweep.py NormalSweep. The -pql flag renders at low quality for fast preview; switch to -pqh for production output.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;_What you get: a curve that draws itself, shades the 68% region, then morphs wider as sigma doubles — the relationship between sigma and spread made immediately visible.&lt;br&gt;
_&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Part 2: Probability from First Principles&lt;/strong&gt;&lt;br&gt;
Animated probability trees&lt;br&gt;
Conditional probability is notoriously difficult to teach. The formula is simple; the intuition is not. An animated tree that builds itself branch by branch changes that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from statanim.probability.tree import ProbabilityTree3D

class ConditionalProb(Scene):
    def construct(self):
        tree = ProbabilityTree3D(
            branches={"Rain": 0.3, "No Rain": 0.7},
            conditionals={
                "Rain":    {"Carry Umbrella": 0.9, "No Umbrella": 0.1},
                "No Rain": {"Carry Umbrella": 0.2, "No Umbrella": 0.8}
            }
        )
        tree.move_to(ORIGIN)
        self.play(tree.build())
        self.wait(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tree renders left to right, labelling each branch as it draws. Joint probabilities at the leaves are calculated and displayed automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Birthday Paradox&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most effective demonstrations of counterintuitive probability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from statanim.probability.classical import BirthdayParadox3D

class Birthday(Scene):
    def construct(self):
        scene = BirthdayParadox3D()
        self.play(scene.animate_growth())
        self.wait(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The animation shows the probability of a shared birthday growing with room size — the curve crossing 50% far sooner than most people expect is the moment that tends to land hardest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0jo82dfcse7cpeeq71i6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0jo82dfcse7cpeeq71i6.gif" alt=" " width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 3: Statistical Inference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Confidence intervals — the most misunderstood concept in statistics&lt;br&gt;
Ask ten people what a 95% confidence interval means. &lt;br&gt;
A significant number will say “there’s a 95% chance the true parameter is in this interval.” That’s not what it means — and animating repeated sampling makes the correct interpretation viscerally clear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from statanim.inference.confidence import ConfidenceInterval3D

class CIDemo(Scene):
    def construct(self):
        ci = ConfidenceInterval3D(
            true_mean=0,
            sigma=1,
            n=30,
            confidence=0.95,
            n_samples=20
        )
        self.play(ci.animate_sampling())
        self.wait(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This draws 20 confidence intervals from repeated samples of size 30. Roughly 19 capture the true mean (marked with a vertical line). The one or two that miss it make the frequentist interpretation concrete in a way no amount of re-reading the definition achieves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hypothesis testing — Type I and Type II errors&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from statanim.inference.hypothesis import HypothesisRegion3D

class HypothesisTest(Scene):
    def construct(self):
        h = HypothesisRegion3D(
            null_mean=0, alt_mean=1.5,
            sigma=1, alpha=0.05
        )
        self.play(h.show_null())
        self.play(h.show_critical_region())
        self.play(h.show_alternative())
        self.play(h.show_type2_error())
        self.wait(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sequence draws the null distribution, marks the critical region (Type I error), then overlays the alternative distribution and shades the Type II error — showing exactly why reducing alpha increases beta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting started&lt;/strong&gt;&lt;br&gt;
The package is at v0.1.2, MIT licensed, and actively developed. Issues and contributions are welcome on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/statanim/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rishabhbhartiya/STATANIM" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rishabhbhartiya/STATANIM/blob/main/API_REFERENCE.md" rel="noopener noreferrer"&gt;API Reference&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built on Manim Community. Statistical algorithms from SciPy and NumPy. Inspired by the mathematical animation work of 3Blue1Brown.&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>statistics</category>
      <category>manim</category>
    </item>
    <item>
      <title>I turned your GitHub contribution graph into a 3D city you can drive through</title>
      <dc:creator>Rishabh Bhartiya</dc:creator>
      <pubDate>Wed, 01 Apr 2026 10:27:04 +0000</pubDate>
      <link>https://dev.to/rishabhbhartiya/i-turned-your-github-contribution-graph-into-a-3d-city-you-can-drive-through-5acj</link>
      <guid>https://dev.to/rishabhbhartiya/i-turned-your-github-contribution-graph-into-a-3d-city-you-can-drive-through-5acj</guid>
      <description>&lt;p&gt;Every developer has that green squares grid on their GitHub profile. You stare at it, feel guilty about the gaps, and move on.&lt;/p&gt;

&lt;p&gt;I wanted to make it feel alive. So I built &lt;strong&gt;GitCity&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is it?
&lt;/h2&gt;

&lt;p&gt;GitCity transforms your GitHub contribution history into an interactive isometric 3D city. Every day you commit, a building grows. The more commits, the taller the tower. Years of consistent coding turns into a proper skyline.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Try it: &lt;a href="https://gitcity.natrajx.in" rel="noopener noreferrer"&gt;gitcity.natrajx.in&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The feature nobody expected
&lt;/h2&gt;

&lt;p&gt;You can switch to &lt;strong&gt;simulation mode&lt;/strong&gt; and drive a car through the city you built with your code.&lt;/p&gt;

&lt;p&gt;It started as a joke. It's now the thing everyone screenshots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frishabhbhartiya%2FGitCity%2Fblob%2Fmain%2Fscreenshots%2Fcardriving.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frishabhbhartiya%2FGitCity%2Fblob%2Fmain%2Fscreenshots%2Fcardriving.gif" alt="Driving simulation" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🏙️ Isometric 3D city from your GitHub contributions&lt;/li&gt;
&lt;li&gt;🚗 Driveable city simulation mode&lt;/li&gt;
&lt;li&gt;🎨 6 themes — Matrix, Noir, Aurora, Ocean, Gold, Ice&lt;/li&gt;
&lt;li&gt;📅 Filter by year, month, or week&lt;/li&gt;
&lt;li&gt;🔗 Embeddable SVG — one URL drops your skyline into any README&lt;/li&gt;
&lt;li&gt;🔓 No login needed — just enter any GitHub username&lt;/li&gt;
&lt;li&gt;✅ Free and open source&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add it to your README
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;GitCity&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://gitcity.natrajx.in/api/svg?username=YOUR_USERNAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try it with &lt;code&gt;torvalds&lt;/code&gt; to see what a legendary skyline looks like:&lt;br&gt;
👉 &lt;a href="https://gitcity.natrajx.in/torvalds" rel="noopener noreferrer"&gt;gitcity.natrajx.in/torvalds&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech stack
&lt;/h2&gt;

&lt;p&gt;Built with React, Vite, and Three.js for the 3D rendering. Deployed on Vercel. GitHub contribution data fetched via the public API — no token required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open source
&lt;/h2&gt;

&lt;p&gt;The full source is on GitHub — PRs and feedback welcome.&lt;br&gt;
👉 &lt;a href="https://github.com/rishabhbhartiya/GitCity" rel="noopener noreferrer"&gt;github.com/rishabhbhartiya/GitCity&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love to hear what your city looks like — drop your username in the comments!&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
