5.4.16 · D5Scientific Computing (Python)
Question bank — 2D plots — line, scatter, bar, histogram, contour, imshow

The figure above shows the same 12 numbers rendered as a scatter (positions only), a histogram (counts per bin), and a contour slice-map — the three traps this page keeps returning to.
True or false — justify
A line plot guarantees your data is a smooth curve.
False. A line plot draws straight segments between consecutive points; smoothness is an illusion from using many close points. With 5 points a sine looks jagged.
scatter and plot become identical if you turn off the connecting line in plot.
Nearly identical visually, but the APIs differ:
plt.plot(x, y, "o") (marker-only) draws every point in one shared style and color, while plt.scatter(x, y, s=..., c=...) lets each point carry its own size and color — extra data dimensions plot cannot express per point.A histogram is just a bar chart of your raw data values.
False. A bar chart draws one bar per category you supply; a histogram counts samples into value-ranges (bins) and throws the individual values away, keeping only frequency .
Setting density=True on a histogram makes the bar heights sum to 1.
False. It makes the total area equal 1 (heights become , where is sample count and is bin width). Heights sum to 1 only in the special case .
In imshow, the array index Z[i, j] maps i to the x-axis and j to the y-axis.
False.
imshow treats rows as y and columns as x, so Z[i, j] = Z[row, col] = Z[y, x] — the opposite of the usual (x, y) reading order.A contour line always encloses a region.
False. A contour at level is the set ; for a saddle or an edge-cropped surface it can be an open curve that runs off the plot without closing.
plt.plot(...) and ax.plot(...) do exactly the same thing.
False in intent.
plt.plot draws on a hidden current axes; with multiple subplots you can't reliably say which axes gets it. The explicit ax. API always targets a known axes.Contour lines drawn close together mean the surface is nearly flat there.
False. Close contours mean a steep slope — you cross many height levels over a small horizontal distance, exactly like tightly packed elevation lines on a map.
Spot the error
ax.contour(xs, ys, Z) where xs and ys are 1D from linspace.
The error is passing 1D coordinates directly for a surface. You must first build 2D grids with
np.meshgrid (which broadcasts the two axes into a full coordinate table — see NumPy meshgrid and broadcasting); Z must be 2D shaped (len(ys), len(xs)).ax.imshow(Z) used to show a math matrix, then complaining the plot is "upside down".
imshow defaults to origin="upper" (row 0 at the top, image convention). For a math matrix with y increasing upward, pass ==origin="lower"==.ax.hist(data, bins=2000) on 300 samples, then puzzling over a spiky, gap-filled shape.
Too many bins for the sample count — most bins get , so shape drowns in noise. Use roughly here.
ax.bar(labels, vals, width=1.0) and the bars touch with no gaps, reading like a histogram.
width=1.0 fills the entire unit spacing between integer positions. Use width < 1 (e.g. 0.6) so categories read as visually separate blocks.ax.imshow(Z, cmap="inferno") with no colorbar, presented as a finished heatmap.
Color is meaningless without a key. Add
fig.colorbar(...) so the reader can map color back to value — and pick a perceptually uniform map (see Colormaps and perceptual uniformity (viridis)).A script ends with ax.plot(x, y) and nothing appears when run from the terminal.
Missing
plt.show(). Notebooks auto-render, but a plain script needs the explicit call to open the figure window.ax.plot(x, y) where x is unsorted, producing a line that zig-zags back on itself.
plot connects points in the order given, not sorted order. Sort by x first, or use scatter if order is genuinely meaningless.Why questions
Why does a histogram divide by (sample count times bin width) when density=True?
So the summed bar area equals 1. Bar has area . Summing: , using the identity (every sample lands in exactly one bin). This matches a probability density — see Probability density functions and normalization.
Why use meshgrid for contour instead of just two 1D arrays?
A surface needs a value of at every combination — a 2D table.
meshgrid expands the two 1D axes into two 2D coordinate grids so you can evaluate over the whole plane at once.Why does c=x on a scatter plot count as "dual coding"?
Dual coding is a cognitive-science idea: a viewer absorbs information faster when it arrives through two channels at once (here, position and color) rather than one. Position already spends both axes; mapping color to a third variable adds a third dimension onto a flat 2D canvas without a 3D plot.
Why does alpha=0.7 help on a dense scatter plot?
Transparency lets overlapping points stack visually darker, revealing where many points pile up — information you'd lose with fully opaque dots that just paint over each other.
Why is Figure different from Axes, and why care?
The Figure is the whole canvas; an Axes is one coordinate system inside it. Caring keeps you in control when a figure holds several subplots — each is its own
ax.Why does extent=[-3,3,-3,3] matter in imshow?
Without it, axes are labeled by pixel/array indices (0..N).
extent remaps those indices to real world coordinates so ticks read as actual x, y values.Edge cases
What does a line plot with exactly one point look like?
Nothing visible by default — a line needs two points to draw a segment. You'd have to add a marker (
marker="o") to see the lone point.What happens to ax.hist when every sample has the same value?
All counts collapse into a single bin ( for one bin, for the rest), giving one tall bar. The range has zero width, so Matplotlib pads it slightly to draw anything at all.
What does a contour of a perfectly flat surface show at levels=8?
Almost nothing. When the data's
min == max, Matplotlib's auto-locator finds no interval to place levels in, so requested levels that don't lie strictly between distinct min and max are dropped — the flat plane is one single level with no boundary to trace, so no curves appear.How does imshow behave when Z contains a NaN cell?
That cell is drawn in the colormap's "bad" color, which by default is transparent — so exact appearance depends on the colormap. For reproducibility set it explicitly:
cmap = plt.get_cmap("inferno").copy(); cmap.set_bad(color="grey"), so masked/NaN data always shows the same way.What does density=True do for a histogram of just one sample?
With , one bin gets that sample (); its height becomes so area is still 1. The "distribution estimate" is meaningless at , but the normalization identity still forces area 1.
For contour, what if you request levels outside the surface's value range (e.g. level 10 on a Gaussian that peaks at 1)?
No curve is drawn for that level — the set is empty, so it's silently skipped.
Recall One-line self-test
Cover the answers. If you can justify each verdict in your own words (not just guess T/F), you own the concept. The trap is always in the reasoning, not the label.