Visualizing Summations from Concrete Mathematics
A table tells you the values of a summation. A graph tells you its shape. In this post, we use Python to plot running totals, compare them with closed forms, and make the difference between linear, quadratic, and cubic growth visible at a glance.
The summation we will graph
$$\sum_{k=1}^{n} k = \frac{n(n+1)}{2}$$This is the sum of the first n positive integers. It grows faster than a straight line, which is why the graph curves upward.
Computing partial sums with accumulate
from itertools import accumulate
def partial_sums(n: int) -> list[int]:
if n < 0:
raise ValueError("n must be non-negative")
return list(accumulate(range(1, n + 1)))
A partial sum is just the running total after each new term is added.
Plotting the running total against the closed form
import matplotlib.pyplot as plt
from itertools import accumulate
n = 50
x = list(range(1, n + 1))
y = list(accumulate(range(1, n + 1)))
closed = [k * (k + 1) // 2 for k in x]
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, y, label="Partial sums", linewidth=2)
ax.plot(x, closed, label="Closed form", linewidth=1.5, linestyle="--")
ax.set_title("Growth of 1 + 2 + ... + n")
ax.set_xlabel("n")
ax.set_ylabel("Sum")
ax.legend()
ax.grid(True)
plt.tight_layout()
plt.show()
If both lines sit on top of each other, that confirms the running total and the formula agree.
Why the curve bends upward
The closed form is:
$$\frac{n(n+1)}{2}$$For large n, this behaves like \(n^2/2\), so the growth is quadratic rather than linear.
Comparing several summations
| Summation | Closed form | Growth |
|---|---|---|
| \(\sum_{k=1}^{n} 1\) | \(n\) | Linear |
| \(\sum_{k=1}^{n} k\) | \(n(n+1)/2\) | Quadratic |
| \(\sum_{k=1}^{n} k^2\) | \(n(n+1)(2n+1)/6\) | Cubic |
from itertools import accumulate
import matplotlib.pyplot as plt
n = 50
x = list(range(1, n + 1))
sum_ones = list(accumulate(1 for _ in x))
sum_k = list(accumulate(k for k in x))
sum_k_sq = list(accumulate(k * k for k in x))
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, sum_ones, label="sum of 1s")
ax.plot(x, sum_k, label="sum of k")
ax.plot(x, sum_k_sq, label="sum of k squared")
ax.set_title("Comparing growth rates of summations")
ax.set_xlabel("n")
ax.set_ylabel("Cumulative sum")
ax.legend()
ax.grid(True)
plt.tight_layout()
plt.show()
Seeing the lines pull apart makes the difference between linear, quadratic, and cubic growth much easier to understand at a glance.
One practical plotting note
Matplotlib is excellent for local scripts, notebooks, and teaching. For a blog post, pre-generated images are often more reliable than trying to run plotting code directly on the page.
Related reading: Python Requests vs urllib
Comments