Skip to main content
Data Visualization and Interpretation

Matplotlib: Advanced Plot Types and Real Data Sources

Published: 2026-08-11
Level: postgraduate
Audience: Postgraduate students in Data Visualization and Interpretation

Prerequisite Knowledge

This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.

Previously Covered in This Subject

  • Matplotlib plotting basics — line charts with plt.plot, markers, labels, grids, and subplots, covered in Lecture 12
  • Bar charts — dot plots versus bar charts and floating bar charts, covered in Lecture 3
  • Bar charts and pie charts — the bar-chart-versus-pie-chart comparison, covered in Lecture 4
  • Histograms — histograms for distributions, covered in Lecture 4
  • Time-series line charts — time series plots versus line graphs, covered in Lecture 4
  • Geographic visualization — geospatial data visualization and automatic mapping, covered in Lecture 4
  • Python visualization libraries — the Python libraries landscape (matplotlib, Bokeh, Seaborn), covered in Lecture 5

13.1 Recap: Where We Left Off

13.1.1 The Roadmap: Matplotlib, Then Seaborn and Bokeh

The question that opens this session: you have built line charts, scatter plots, and subplots with matplotlib — but what comes next, and why does it all rest on the library you are learning right now?

This session wraps up matplotlib, and with it module four of the course comes to an end. The plan for the coming classes: next comes Seaborn, then Bokeh, two more Python libraries that are built on top of matplotlib. Seaborn and Bokeh add a different layer of capability, including much more interactivity, so the matplotlib you learn here is the foundation you will reuse in both. We have a small number of classes left, and they will be spent on these two libraries.

Think of matplotlib as the engine of a car, and Seaborn and Bokeh as different bodies and dashboards built around that same engine. Seaborn takes matplotlib figures and gives them statistical styling and built-in statistical plot types with one or two lines of code; Bokeh takes the same matplotlib-style plotting ideas and renders them as interactive web plots you can pan and zoom. Neither replaces what you learn here — both call matplotlib underneath, so every command you master in this session keeps working inside them. The analogy holds in one important way too: if the engine changes its API, the bodies on top feel it — which is why matplotlib's conventions, once learned, transfer almost unchanged into the rest of the ecosystem.

13.1.2 What We Covered Last Time

The previous class started with a comparison between data visualization tools like Power BI and Python, and how the drag-and-drop tools differ from a programming approach. Then we looked at when matplotlib came into the picture, including the interesting fact that it is built on top of Matlab. From there we began working with the library itself. We covered the basic plot types and did examples of plotting. We learned about markers: what markers are and how to change their color, shape, and other properties using commands. We built a simple line chart with matplotlib, learned about labels, and drew grids using the X and Y axis parameters. We also learned subplotting, which lets us have multiple plots next to each other in matplotlib. We saw the different ways to set up a working environment: installing Anaconda, using Jupyter notebooks, which are quite popular, and Google Colab. All of these are free options for running the same code.

That recap gives a compact checklist you should be able to do without looking anything up: plt.plot(x, y) for a line, plt.scatter(x, y) for points, plt.xlabel, plt.ylabel, and plt.title for labels, plt.grid(True) for the grid, and plt.subplot(rows, columns, sequence) for layouts. Today's session adds four more plot types and three real data sources on top of these.

13.1.3 Subplot Parameters: Rows, Columns, Sequence

There is a specific sequence to the subplot command that is worth locking in: the first parameter tells the row, the second tells the column, and the third tells the sequence of the plot, meaning its position in the layout.

The subplot call reads as a grid address. If you ask for plt.subplot(2, 3, 4), the first argument is the number of rows, the second argument is the number of columns, and the third argument is the position, counted left to right, top to bottom:

So in a grid, position 4 sits at row 2, column 1 — the first cell of the second row. Position 5 would be row 2, column 2. The position number fills the grid like reading a book: across the first row, then across the second row. Every symbol here: rows, columns, and position 4 out of possible cells.

In the recap demo we created six plots by stepping through these parameters, and matplotlib placed them next to each other depending on the position we gave.

Exam note: this parameter convention is an easy thing to test, so remember the order — row, column, sequence. A common trap is reversing the first two: swapping rows and columns in plt.subplot(2, 3, 4) gives a grid where position 4 lands in a different cell entirely. The sequence always counts across the row first, then down.

13.1.4 Interactive Mode: Why Graphs Appear Immediately

One small behavior tripped up the recap demo: interactive mode was turned on in the notebook. When interactive mode is on, the moment you run a plotting command, matplotlib shows that graph immediately, and it does not wait for the final command. That is why the subplots appeared one by one as we ran the cells instead of lining up side by side at the end. The behavior itself is useful when you want to inspect each plot as you go, but it is worth knowing that it changes when plots appear.

Interactive mode is a timing switch, not a plotting switch. In the default (non-interactive) mode, matplotlib collects every command and draws the figure only when plt.show() runs — that is why a fully decorated figure appears at once. With interactive mode on (plt.ion() in scripts; Jupyter's %matplotlib magic does something similar), each plotting command draws immediately. The symptoms to expect in a notebook: figures appear cell by cell, earlier than you asked for them, and separate calls do not merge into one figure. If your plots pop up "too early" or never combine, check whether interactive mode is on.

The practical takeaway from the recap: know the default behavior (draw on show()), know the switch, and if a notebook is set to interactive, remember that every cell is a checkpoint — each plot shows as soon as it is created. That is expected behavior, not a broken notebook.

Exam note: the study advice for this session is repeated and consistent — practice is essential. Just listening will not help; run every example yourself in free tools like Anaconda, Jupyter, and Google Colab. The plotting commands stick only when your own hands execute them, and the subplot row-column-sequence order is exactly the kind of small detail that a hands-on run makes unforgettable.

13.2 Scatter Plots

13.2.1 Plotting Points with plt.scatter

The hook: how do you show whether two measurements move together — for example, whether taller people tend to weigh more? The answer is the simplest plot type there is: put one measurement on each axis and draw one dot per person.

The scatter plot is the simplest plot type to add to your toolkit. Recall that plt (pyplot) is the main library that actually does the plotting. The moment you say plt.scatter(x, y), matplotlib creates a scatter plot from the values you pass. In the example we used the same two libraries as always, matplotlib for plotting and NumPy for numbers, and passed arrays of X and Y values. A point is then drawn for every pair in the arrays.

Every dot is a pair, drawn at matching array positions. The two arrays must line up element by element:

The first element of pairs with the first element of , the second with the second, and so on. Matplotlib places the -th dot at horizontal position and vertical position :

If the arrays have different lengths, there are not enough pairs, and matplotlib raises an error instead of guessing.

The scatter plot shows where the points sit — that is its whole purpose: to reveal relationships between two variables before any curve or model is imposed on them. The vertical axis is the Y (dependent) measurement, the horizontal axis the X (independent) measurement.

Worked example: two tiny arrays. Suppose a shop records, for four days, the number of ads shown and the number of visitors:

  • (ads shown, in hundreds)
  • (visitors, in hundreds)

plt.scatter(x, y) draws four dots: (2, 10), (4, 14), (6, 16), and (8, 20). Reading the first dot: at 200 ads there were 1,000 visitors. The dots rise as you move right, so the picture already suggests that more ads go with more visitors — a relationship that a table of numbers hides but a scatter plot shows at a glance. Sense-check: each pair appears at its own coordinates, no line connects them, and the upward drift of the dots matches the fact that every Y value in the list is bigger than the previous one.

If we had written plt.plot instead of plt.scatter, the same values would have been drawn as a line. That one command name is the difference between a scatter of points and a connecting line.

Comparison — plt.plot vs plt.scatter (same data, different message):

Plot command What it draws Best when What it hides
plt.plot(x, y) Points connected by a line Data has order: time series, a function's values Line may imply values between the points that were never measured
plt.scatter(x, y) Points only, no line Two measurements with no natural order: height vs weight, price vs volume The shape of change between points

The rule of thumb: if the data is a sequence in time, draw a line; if it is a collection of independent measurements, draw dots. When in doubt, remember the command name is the entire difference — scatter leaves the dots alone, plot joins them up.

Assumptions and scope. A scatter plot assumes both arrays are the same length, numeric, and aligned in pairs. It shows association (points rising together, falling together, or scattered randomly), but never causation — a rising pattern can come from a third hidden variable. It also makes no claim about values between the dots: the gaps are simply unmeasured.

Pitfalls.

  1. Mismatched array lengths — one array longer than the other produces an error; check the counts before plotting.
  2. Reading causation into a pattern — ice cream sales and drowning deaths both rise in summer; the dots correlate, but neither causes the other. The scatter plot only reports what the data shows.
  3. Confusing plot with scatter — with time-ordered data a connecting line is usually what you want; with independent pairs the line invents a story between measurements that were never taken.
  4. Forgetting to label the axes — a scatter plot without axis labels is unreadable to anyone else; plt.xlabel and plt.ylabel cost one line each.

Visual intuition: picture the finished figure — the horizontal X axis (the independent measurement, with its units) on the bottom, the vertical Y axis on the left. Each dot is a small marker sitting at its pair of coordinates; markers never touch across gaps, so the eye reads density, drift, and outliers at once. A cloud that slants up-left to down-right means one variable falls as the other rises; a round, even cloud means no visible relationship. The one-sentence takeaway: a scatter plot turns two parallel lists of numbers into a picture of their relationship.

Recap: plt.scatter(x, y) draws one dot per pair; plt.plot(x, y) connects the same dots with a line. Choose dots for independent measurements, lines for ordered sequences — and keep the arrays the same length. This is also the pattern the bar chart repeats next: pass two aligned arrays and let matplotlib do the drawing.

Real-world connection: scatter plots are the standard first look in almost every data-driven field — medical researchers plot dosage against response to see whether a drug effect rises with dose, economists plot inflation against unemployment, and in this course's running example, price against volume for a stock shows which trading days had unusual activity. Wherever a dashboard shows a cloud of dots, a scatter plot is doing the work.

13.3 Bar Charts

13.3.1 Vertical Bars with plt.bar

The hook: how do you compare the sizes of a few categories — sales per region, votes per party, height per country? A bar chart answers with geometry: the category sits on one axis, and the bar's length is the number.

For the bar chart example we created two variables: X as the labels A, B, C, D and Y as the values. Calling plt.bar(x, y) plotted the graph, one bar per label with the height given by the Y value. The variables stay in memory, so you can keep re-plotting them with different commands without recreating them.

A bar chart is a scatter plot's categorical cousin. The X array holds labels (categories) instead of numbers, and the Y array holds one value per category:

plt.bar(x, y) draws four vertical bars: bar A rises to height , bar B to , and so on. The bar height is the value itself, so comparing values becomes comparing lengths — exactly what the human eye is good at.

A useful property shown in the demo: the variables live in memory, so re-plotting with a new command costs nothing. You do not retype the data; you just call the next plotting function and the same variables are reused.

13.3.2 Horizontal Bars with plt.barh

If you say plt.barh instead of plt.bar, you get the horizontal bar chart, because matplotlib simply turns the same values around. The same X and Y variables worked again because they were still in memory.

Comparison — plt.bar vs plt.barh:

Command Bar orientation Value drawn as Fits best when
plt.bar(x, y) Vertical Height Few categories with short labels
plt.barh(x, y) Horizontal Width Many categories, or long category names that would overlap when vertical

When to pick which: with ten categories named "State Bank of India" and "International Trade Corporation," horizontal bars keep every label readable; with four short letters, vertical bars are the natural choice. The rule of thumb is the same data, one flipped axis.

13.3.3 Controlling Color, Width, and Height

Beyond X and Y you can pass extra parameters. color fills the bars with the color you choose. There are many ways to give a color: a list of predefined soft colors, of which there are more than a hundred named ones (for example light pink), or a hex value, or an RGB value. width controls the width of the bars, and for horizontal bars the height parameter controls the height. When you pass only width and no color, the bars keep the default color and just change shape.

Worked example: controlling a bar chart. Start with the demo's four categories and pick four values — say for labels A, B, C, D.

plt.bar(x, y, color="lightpink", width=0.6)

The bars are filled with the named color lightpink and each bar is 0.6 units wide instead of the default width. The default width in matplotlib is 0.8, so width=0.6 produces visibly slimmer bars with more space between them. For the horizontal version:

plt.barh(x, y, color=["red", "blue", "green", "yellow"], height=0.5)

Now the color is a list of four colors, matched one-to-one with the four bars — bar A is red, bar B is blue, and so on — and height=0.5 makes each horizontal bar 0.5 units tall. Sense-check: the vertical example changes the whole set with one color value; the horizontal example needs a four-item list because every bar gets its own color. A single color value applies to all bars; a list applies per bar.

The color options are the same family you saw with markers: a named color from the hundred-plus built-in palette (like "lightpink"), a hex value like "#FF69B4", or an RGB triple. Whatever you specify for color, width, or height, the rule is the same — extra parameters adjust the bars' look, never their data.

13.3.4 Programmatic Control vs Drag-and-Drop Tools

This is one of the real strengths of Python. In a drag-and-drop tool you pick a template and it applies to everything, but here you can set the exact width, size, color, and angle of every element programmatically, per plot. The tools definitely come with the edge of drag and drop, but if you know programming, matplotlib gives you much more control. That control, plus the very good documentation of the project and a well-established community, is why the matplotlib website is full of ready-made examples: you have to learn the concept and then just apply it to your business case.

The template-vs-programming trade-off (from the session). A drag-and-drop tool (Power BI, Tableau) applies one template to everything you drop in; a programmatic tool lets you fix the exact width, size, color, and angle of every element of every plot — and then re-run the same recipe on the next dataset. Drag and drop wins on speed to first draft; Python wins on precision, repetition, and automation. Once the concept is understood, the documentation's ready-made examples make it a matter of applying the concept to your business case rather than inventing anything from scratch.

Pitfalls.

  1. Color list length mismatch — passing a color list with fewer entries than bars makes matplotlib complain or silently reuse colors; keep the list the same length as the categories.
  2. Bar width too large — a width bigger than the spacing between labels makes bars overlap; the default 0.8 leaves gaps, wider values erase them.
  3. Labels vs numeric Xplt.bar with numeric X treats the numbers as evenly spaced categories; the axis ticks may not show the category names unless you set them.
  4. Choosing the wrong orientation — long category names as vertical bars crowd and overlap; that is what plt.barh exists for.

Recap: plt.bar draws vertical bars (value = height), plt.barh draws horizontal bars (value = width), and both take the same two aligned arrays — labels in X, values in Y. color, width, and height are per-plot adjustments that never touch the underlying data. The variables stay in memory, so re-plotting is a one-line change.

Real-world connection: bar charts are the workhorse of business reporting — revenue by quarter, market share by company, population by country — because a decision-maker reads lengths faster than a table of numbers. In the finance dashboards this course keeps returning to, bar charts compare one day's trading volume against another's at a glance, and the same plt.bar(x, y) call with the same variables produces the chart in any tool that runs Python.

13.4 Histograms

13.4.1 Generating Random Data

The hook: a scatter plot needs a second variable, a bar chart needs categories — but what if you only have one list of numbers and want to see where the numbers crowd together? A histogram answers by counting how many values fall into each stretch of the number line.

A histogram is created just by changing the plot style, telling matplotlib that this time we want a histogram. In the example, a random function from NumPy generated the numbers. The call asked for 250 values, with a mean of 170 and a standard deviation of 10. The most natural reconstruction of that description is a normal distribution:

Reading the reconstruction. The statement reads: "the random variable follows a normal distribution (the bell-shaped distribution that describes heights, measurement noise, and many natural quantities) with a mean — the center of the bell — and a standard deviation — the typical distance of a value from the center." The NumPy call matching this description is:

x = np.random.normal(170, 10, 250)

where the first argument is the mean, the second is the standard deviation, and the third is the number of values to draw. This matches the reference book's pattern of generating random data with NumPy and feeding it to plt.hist().

The standard deviation is the parameter ; the variance is its square, . The session gave the standard deviation directly, so and not — the typical mistake is to treat the 10 as the variance and then wrongly take (the square root of 10). Here the spread parameter is the one that was stated.

To see how the numbers behave, the bell shape puts most values within one standard deviation of the mean: roughly 68% of the 250 values (about 170 of them) fall between and , and roughly 95% (about 237 values) fall between and 190.

The histogram is created just by telling matplotlib the style:

plt.hist(x)

plt.hist counts how many of the 250 values land in each bin — a fixed stretch of the number line — and draws one vertical bar per bin whose height is that count. Matplotlib chooses sensible bin edges automatically, and you can set them yourself with the bins parameter (for example, plt.hist(x, bins=20) for 20 bins).

13.4.2 Reading the Histogram Output

When we ran it, the histogram came out with its peak around 170, exactly where the numbers concentrate, and the spread matched a standard deviation of 10.

Worked example: what the shape tells you. The bins run along the horizontal X axis from about 140 to 200, and the bar heights (the counts) run up the vertical Y axis. Because the values were drawn from a normal distribution centered at 170:

  • The tallest bars sit at the middle, around 170 — where the concentration is highest.
  • The bars shrink steadily toward both ends — the 150s and the 190s — where fewer values land.
  • The two tails are roughly symmetric: about as many low values as high values.

A concrete reading: with , if the tallest bin holds about 40 values, that bar's height is 40 — nearly one in six of all the numbers falls in that single stretch near the center. Sense-check: a bell-shaped histogram whose middle bar is tallest and whose ends taper down matches the normal distribution we asked for; if the peak were off at 160 or the shape lopsided, the data would not match the stated parameters.

Pitfalls.

  1. Treating the standard deviation as the variance — the session said directly; the variance is the square, . Do not square the 10 and then use it as the spread.
  2. Misreading the bar height as a value count in the wrong units — each bar's height is a count of values in that bin, not a data value; the data values live on the X axis.
  3. Thinking the bin choice is free of consequence — too few bins hides the shape, too many bins makes jagged noise; the reference book shows the shape changes as the bin size changes.
  4. Forgetting a fixed seed means reproducibility — with no seed, every run draws a fresh sample, so the exact histogram changes each time (see below).

Visual intuition: name the axes — X is the measurement scale (here, the height-like values around 170), Y is the count of values in each bin. The shape is a bell: a single peak at the middle, symmetric slopes down on both sides, tails thinning out near 140 and 200. The landmark is the peak at 170, and the takeaway in one sentence: the histogram turns "250 numbers" into a picture of a bell centered at 170 whose width matches a standard deviation of 10.

Because the numbers are random, the graph changes on every run: no seed is fixed, so each execution draws a fresh sample. That is why the histogram looked slightly different each time it was generated.

Why the graph changes every run (from the session). The random generator starts from a different internal state on every execution, so the 250 values are never the same twice — and neither is the histogram. The shape stays a bell around 170 (the parameters do not change), but the exact bar heights wobble from run to run. If you want the same numbers every time, fix a seed before drawing, for example np.random.seed(42) — the reference book does exactly this in its random-data examples to keep results reproducible. With a seed, the same run gives the same histogram; without one, expect variation.

Recap: a histogram is a bar chart of counts per bin — it shows the distribution of one numeric column. Here, 250 values from a normal distribution with mean 170 and standard deviation 10 produced a bell-shaped histogram peaking at 170; no fixed seed means a fresh (but similar) graph on every run.

Real-world connection: histograms are the first thing a data scientist looks at before any analysis — a bank plots the histogram of customer balances to see how many accounts are tiny and how many are large, a hospital plots the distribution of patient wait times to find the load on the system, and in the finance example running through this course, a histogram of a stock's daily returns shows how often the price moves a little versus a lot. The same plt.hist call serves every field.

13.5 Pie Charts

13.5.1 The Theory: Starting at the X Axis, Anticlockwise

The hook: a pie chart answers a part-to-whole question — what share of the total does each category hold? The subtlety is that the answer depends on where the chart starts drawing and which direction it sweeps, because that decides which label lands on which slice.

There is a bit of theory to the pie chart. A pie chart in matplotlib always starts from the X axis, the horizontal line at zero degrees, and then fills in the anticlockwise direction. Whatever values you give, it goes backward from that start and fills the slices in order. In the example the values were 35, 25, 25, and 15, so 35 became the first, largest slice, then 25, then the other 25, then 15.

The filling convention (professor's analogy, extended). Picture the pie like a clock face lying flat, with the three o'clock position (the X axis) as the starting mark. Matplotlib begins there and sweeps the slices anticlockwise — against the direction the clock hands turn — filling each slice in the order the values were given. The first value takes the first sweep of the circle, the second takes the next, and so on. This convention is why the sequence of your array is not a detail: value order equals slice order around the circle.

The reference book states the same geometry: the pie is a circular representation of component ratios, where the angle (and so the arc length) of each sector presents the proportion that component accounts for relative to the whole.

13.5.2 The Slice Math

The four example values happen to add up to 100:

So each slice is exactly its percentage of the full circle. The general rule is that the angle of a slice is proportional to its value:

where is the value of slice and is the total of all slice values.

Worked example: computing every slice angle. Take the four demo values . The total is:

Each slice angle follows the rule :

Check the arithmetic by adding the angles back up: — the full circle, exactly as it must. Sense-check: the largest value (35) takes the largest share of the circle (126 degrees, more than a third of 360), and the smallest value (15) takes the smallest slice (54 degrees, 15% of the circle); since the values sum to 100, each angle in degrees is just the percentage times 3.6.

The rule works for any values, not only those summing to 100. If the values were , the total is 5, and the first slice gets . The reference book adds the caution that when the values do not fill the whole, the pie is incomplete — with matplotlib draws a fan shape rather than a full circle, so the ratios must be chosen to represent the full set of parts.

13.5.3 Labels, Start Angle, and Slice Order

Labels are passed alongside the values as an array, in the same sequence. With values 35, 25, 25, 15 and the label array apples, banana, cherry, date, matplotlib matched them in order: apples got the biggest slice, then banana, cherry, and date. Knowing the filling direction and the starting point matters here, because that is how the label-to-slice matching works.

You can also control the start angle. By default the pie starts at the X axis (zero degrees); with startangle=90 the pie starts at the 90-degree position and still moves anticlockwise. The example showed the same slices starting from the top of the chart instead of the right-hand side.

plt.pie(y, labels=["apples", "banana", "cherry", "date"], startangle=90)

Why the convention is worth knowing (from the session). The professor notes that programmatically the start direction matters little — matplotlib handles the geometry — but the knowledge of how it fills matters: it is how you predict which label lands on which slice. If you pass labels out of order, the chart quietly shows each label on the wrong slice. The startangle option rotates the whole starting point: default 0 begins at the X axis (the right-hand side); startangle=90 begins at the 90-degree position (the top) and still sweeps anticlockwise from there.

13.5.4 Explode, Shadow, Colors, Legend, and Title

A feature called explode pulls one slice out of the chart: you say how much, by percent, and that portion is separated from the rest. In the demo the first portion was taken out of the pie. Setting shadow=True adds a small shadow behind the pie. You can also change the colors of the pie chart slices by passing an array of colors, either comma-separated colors or a colors array mapped one-to-one with the labels. Adding a legend and your own title is equally simple; the example gave the chart the title Four Fruits, and the legend appeared based on the colors.

Worked example: a decorated pie chart. Continuing with and the four fruit labels:

plt.pie(y, labels=["apples", "banana", "cherry", "date"],
        explode=[0.1, 0, 0, 0], shadow=True,
        colors=["red", "yellow", "pink", "brown"])
plt.title("Four Fruits")
plt.legend()
plt.show()

Reading the parameters one by one: explode=[0.1, 0, 0, 0] pulls the first slice (apples, 35) out of the pie by 10% of the pie's radius — only apples detaches, the other three stay in place. shadow=True draws the drop shadow behind the whole pie. The four colors map one-to-one with the slices in order: red for apples, yellow for banana, pink for cherry, brown for date. plt.title("Four Fruits") labels the chart, and plt.legend() shows a legend built from the labels and their colors. Sense-check: every decoration is a separate, optional parameter — the underlying slices and their 126/90/90/54-degree angles are untouched; explode only shifts the drawing position of the first slice, never its angle.

Pitfalls.

  1. Label order mismatch — labels pair with values by position, so a shuffled label array puts the wrong name on every slice; keep both arrays in the same order.
  2. Values that do not sum to the whole — if the values total less than a full circle (as in the reference book's [0.1, 0.3] example), matplotlib draws an incomplete fan; make the values represent all parts of the total.
  3. Too many categories — with many small slices, a pie becomes unreadable and the angles too thin to compare; bar charts handle many categories better.
  4. Explode values out of range — explode is a fraction of the radius; a value of 1 or more pushes the slice entirely off the chart.

Recap: the pie always starts at the X axis (zero degrees) and fills anticlockwise, with each slice's angle proportional to its value: . Labels match values by position; startangle, explode, shadow, colors, and a legend are all optional decorations.

Exam note: remember the pie chart conventions — it starts at the X axis and fills anticlockwise. This was flagged as a concept to be aware of in the session, and the angle-to-value proportionality is the math behind every slice.

13.5.5 The "Ocean of Commands" Reality Check

A useful honesty note: everything we have seen is scratching the surface. matplotlib is so flexible that you can literally control pixel by pixel, any angle, any dimension, any width, any color, any font, programmatically, and these are still just the very basic commands. There are tons and tons of commands and parameters; it is an ocean. That is exactly why self-learning is always a good habit: learn the pattern of how to look a command up, and the library will do the rest.

The "ocean of commands" note (from the session). Every command in this session is a basic one, yet the library lets you control pixel-by-pixel: any angle, any dimension, any width, any color, any font. The takeaway is a learning habit rather than a list to memorize — learn the pattern of looking a command up (in the documentation and the gallery), and the library does the rest. Self-learning is part of the material, not a supplement to it.

Real-world connection: pie charts appear wherever the part-to-whole story matters — market share by company, budget spent by department, web server usage by product (the reference book's example). In finance and economics, they show the composition of a GDP or a portfolio at a glance; the slice-angle math, once internalized, lets you sanity-check any such chart from the numbers alone.

13.6 Plotting Data from a Database (MySQL)

13.6.1 The Connection Workflow

The hook: every plot so far was fed with arrays typed by hand — but no real business works that way. The data lives in a database that updates daily. How do you turn a live database table into a chart, the way Tableau does with a data source?

So far we passed variables via arrays: X values, Y values, plot, scatter, histogram. In reality we cannot hard-code and type data like that, so we need real data to use. This is where we connect Python to a database, the same way Tableau lets you give a data source, either Excel, a CSV, or different connectors. We remember presenting in an earlier class how to connect to MySQL in Tableau; here we do the same programmatically. The workflow has a fixed shape:

The eight-step database-to-plot workflow. The pattern never changes; only the query text and the column names vary:

  1. Import the libraries. matplotlib for plotting, plus the MySQL connector (because this example uses MySQL; other connectors exist for Oracle and other databases).
  2. Pass the credentials. The user (root), the password, and the host (localhost) go into the connection call.
  3. Build the SQL query as a string. You can literally create a string of SQL with the column names and the table you want.
  4. Create a cursor from the connection: cursor = connection.cursor(). The cursor is the object that talks to the database.
  5. Execute the query with the cursor: cursor.execute(sql_string).
  6. Fetch the data back. The cursor's fetch commands (like fetchall()) bring the rows into Python.
  7. Bring the fetched data into a pandas data frame. Just as NumPy is the library for numbers, pandas is the library for data frames — the tabular structure that column selection and plotting both expect.
  8. Pick the columns you want and plot. The first argument you pass is the X axis, the second is the Y axis, then title and labels.
import matplotlib.pyplot as plt
import mysql.connector
import pandas as pd

connection = mysql.connector.connect(user="root", password="...", host="localhost")
cursor = connection.cursor()
sql = "SELECT trade_date, close_price FROM daily_price WHERE symbol = 'ITC' AND trade_date >= '230401'"
cursor.execute(sql)
rows = cursor.fetchall()
df = pd.DataFrame(rows, columns=["trade_date", "close_price"])
plt.plot(df["trade_date"], df["close_price"])
plt.title("ITC Close Price")
plt.show()
cursor.close()

Read the code from the top: the imports bring in the three tools; the connect call uses the credentials; the SQL string names the columns (trade_date, close_price) and the table (daily_price) and filters with a date literal in YYMMDD format; cursor.execute sends that string to the database; fetchall brings every matching row back; the pandas data frame organizes the rows into named columns; and the last block is exactly the plotting code from earlier sessions — X column, Y column, title.

13.6.2 Live Demo: Stock Prices from the Database

The live demo used a table called daily price in a MySQL database. The query asked for the trade date and the close price for a given symbol, with the date starting from the first of April; the date literal in the query used the YYMMDD format. The first run was for the symbol ITC, and the fetched close prices came out between 750 and 800. Plotting trade date on the X axis against close price on the Y axis produced a line chart of the stock's movement for the month. The same query was then rerun for State Bank of India (SBI) over the same period, and the prices again sat around 750 to 800. Finally the date filter was widened from one month to a whole year, more than a year, from 2023 up to the current month, and the chart showed the full-year movement. One detail: the current month's data was not complete yet, so that month did not show in the chart. You can change the numerical value in the query and the plot follows.

Worked example: one query, three charts. The same skeleton produced every chart in the demo, changing only the WHERE clause:

Query change Resulting chart
symbol = 'ITC', date from April Line chart of ITC's close price, values between 750 and 800
symbol = 'SBI', same date range Line chart of SBI's close price over the same month, again around 750 to 800
symbol = 'ITC', date from 2023 to the current month Full-year line chart of ITC's movement

The third run taught a practical detail: the current month's data is incomplete, so that month's points simply do not appear — the chart ends at the last complete month. Sense-check: changing a number in the query string changes what the database returns, and because the rest of the pipeline (data frame to plot) is untouched, the chart follows automatically.

Pitfalls.

  1. Running only part of the notebook — the cursor is closed at the end of the code, so after you change the query you must run all the cells again, from connection to plot; running only the plot cell reuses a dead cursor.
  2. Date literal format mistakes — the query uses YYMMDD (for example '230401' for 1 April 2023); writing a different format silently returns nothing or the wrong dates.
  3. Credentials in the code — for a class demo root/localhost is fine, but real deployments read credentials from environment variables or secret stores, never from committed code.
  4. Forgetting the title and labels — the plotting block is the same as before: X column, Y column, then title and axis labels; skipping them leaves a chart no one can read.

13.6.3 Why This Pattern Matters

The whole point of the example is that from the moment the data is in a data frame, everything else is the same code you already learned: choose the columns, pass them to plt.plot, set the labels and title, and show. The database only changed the first few steps.

Recap: the database changes only the first part of the workflow — connector, credentials, query, cursor, fetch. The moment the rows land in a pandas data frame, plotting is the same plt.plot you have used all along. Learn the eight-step connection pattern once, and every database behind a dashboard is the same recipe.

Real-world connection: this is the workflow behind live trading dashboards — a chart that refreshes from a database instead of a hand-maintained spreadsheet. A stock desk watches close prices stream from the same daily_price table the demo used, and a bank's operations dashboard pulls transaction volumes from its own tables with the same connector-and-data-frame pattern. Wherever a business chart must reflect a changing database, this eight-step recipe is the bridge.

13.7 Reading Data from CSV Files

13.7.1 The read_csv One-Liner

The hook: a database is one way to get real data — but much of the world's data is delivered as a file: an exported spreadsheet, a download from a data portal, a weekly report. How do you read such a file into a plot with one line of code?

There are scenarios where you have data downloaded from other sources and you want the code to read a CSV file. With pandas this takes one line: pd.read_csv("filename.csv"). Pass the parameter, and the file is read automatically. When the file sits in the same folder as the notebook, just the file name is enough. After that you identify which columns you want, and from here on the code is common: use the plot function, either plt.plot or plt.scatter, pass the X and Y labels, set the title, and show. Compared with the database example, steps one to three change (the connector is replaced by the CSV read), while steps four and five remain broadly the same.

The CSV pipeline replaces the database connector. Where the database recipe used connector, credentials, and SQL, the CSV recipe uses one line:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("stock_data.csv")

Then the plotting part is identical to everything before:

plt.scatter(df["total_quantity"], df["close_price"])
plt.xlabel("Total Quantity (volume)")
plt.ylabel("Close Price")
plt.title("Price vs Volume")
plt.show()

The parallel with the database demo: the connector steps (steps 1–3 there) become a single read_csv call, and the fetch-and-data-frame steps (steps 4–5) are collapsed into the returned df object. Everything after — choosing columns, X, Y, title, labels, show — is the same code you already know.

A CSV (comma-separated values) file stores tabular data as plain text: one row per line, columns separated by commas, with a header line naming the columns. pandas parses that text into a data frame — the same object the database example produced — so column selection like df["total_quantity"] works exactly as before.

13.7.2 Demo 1: Scatter of Volume vs Price

The CSV file had two columns: total quantity (the volume) and close price, both numeric. With X as total quantity and Y as close price, a scatter plot showed the relationship between price and volume: on the day the stock price was above 800, the volume was very high.

Worked example: reading the scatter. The file stock_data.csv in the notebook's folder holds two numeric columns — total_quantity (trading volume) and close_price (the stock's closing price). The code reads it, then draws the two columns:

df = pd.read_csv("stock_data.csv")
plt.scatter(df["total_quantity"], df["close_price"])
plt.xlabel("Total Quantity")
plt.ylabel("Close Price")
plt.title("Price vs Volume")
plt.show()

Every row of the file becomes one dot: its X position is the day's volume, its Y position the day's closing price. The chart shows a cluster of ordinary days and one striking day: when the price was above 800, the volume was very high, so that dot sits far to the right and high up — separated from the rest of the cloud. Sense-check: the scatter makes the exceptional day obvious as an outlier — exactly the pattern a price-versus-volume chart exists to reveal.

The volume numbers are large, which is why the axis looked compressed; you can convert them programmatically into a smaller unit, another advantage of having the data in code rather than fixed inside a tool. Instead of editing the file, you could divide the column by 1,000 (showing volumes in thousands) with one line — the data stays intact, only the display unit changes.

13.7.3 Demo 2: Switching to a Time-Series Line Plot

For a line plot you need a date, because a time series needs a time axis. We saved a new CSV with two fields, date and close price, and uploaded it. Remember that the same code will not run on the new file: the code still expected the total quantity column. The code was updated so that the X field is the date instead of total quantity, and since you cannot put a date on a scatter plot, the plot command was switched from scatter to a simple line plot. The result was the date on the X axis and close price on the Y axis. The axes can be formatted later, but the core change is: bring whatever values you want, then change the plot command accordingly.

df = pd.read_csv("stock_dates.csv")
plt.plot(df["date"], df["close_price"])
plt.xlabel("Date")
plt.ylabel("Close Price")
plt.title("Close Price Over Time")
plt.show()

Why the plot command had to change (from the session). The demo exposed a clean rule: scatter plots need numeric values on both axes; a date is not a numeric value, so a scatter of date against price does not make sense. A time series needs a time axis, so the X field became the date and the command became a simple line plot. The axes can be formatted later; the core change is: bring whatever values you want, then choose the plot command accordingly.

13.7.4 The Upload Pitfall

A recurring, easy-to-make mistake: you change the file locally, forget to upload the new version, and then wonder why the plot still shows the old data. The demo hit exactly that, because the file had been overwritten locally but the notebook was still reading the previous copy. When the data seems stale, check that the file on the notebook side matches the file you are editing.

Pitfalls.

  1. The stale-file trap (from the session). You edit the CSV on your local machine, forget to upload the new version to the notebook environment, and the plot silently shows yesterday's data. If the data seems stale, re-check the uploaded file — the professor hit exactly this snag in the demo.
  2. Column name mismatch. The code references df["total_quantity"]; a new file with different column names raises a KeyError. Update the column names in the code when the file changes.
  3. Wrong plot command for the data type. A date column cannot be scattered; switch to a line plot for time-series fields.
  4. File path issues. If the file is not in the same folder as the notebook, the plain file name fails; pass the full or relative path instead.

Recap: pd.read_csv("filename.csv") reads a CSV into a data frame in one line, the connector steps of the database recipe collapse into that call, and everything after — column choice, plot or scatter, labels, title — is the same plotting code you already know. Change the file, change the columns, change the command accordingly — and re-upload the file.

Real-world connection: CSV is the common currency of data exchange — a stock analyst downloads a broker's daily report, a researcher exports a survey, a government portal publishes economic indicators, all as CSV files. The pandas reader plus a scatter or line plot turns any of these downloads into an immediate picture, and the same read-and-plot pipeline powers the financial dashboards this course keeps returning to.

13.8 Reading Data from the Web (APIs)

13.8.1 Web APIs and the requests Library

The hook: a database and a CSV both need the data to come to you. What if the data lives on someone else's server and updates constantly — stock prices, economic indicators, weather? The answer is an API: the data's owner lets your code ask for it directly.

Many websites now offer their own APIs, with documentation. All the key sites, for example Yahoo Finance, CNBC, and Moneycontrol (its API status still to be checked), have their own APIs; they usually charge, though some allow limited free usage. The advantage is that you do not have to download data into Excel manually: you call the API and fetch the data directly. To download anything from the web you use the requests library. Many people also use requests for web scraping, though scraping may have its own rules; using an API is allowed. The pattern is simple: build the URL, call requests.get(url), and the library returns the data.

What an API is, and how the pattern works. An API (application programming interface) is a standard doorway a service opens for programs: you send it a request describing what you want, and it sends back the data in a structured form. Think of a restaurant menu — you pick from what the kitchen offers (that is the API's documented options), and the kitchen prepares only that; you never walk into the kitchen yourself (that would be scraping). The download pattern is:

  1. Build the URL — a web address that encodes the service, the data you want, and the parameters (here, the country codes).
  2. Call requests.get(url) — the requests library sends the request and returns the server's response.
  3. Check the response — confirm the request was successful before using the data.
  4. Extract the value — pull the needed field out of the returned structure.

The library is called requests because you are requesting data from the server, and the server answers with the data in a standard format (usually JSON) that Python can read.

13.8.2 Demo: World Bank GDP Data

The live example used the World Bank API, which provides real-time data. We created an array of four country codes and an API URL string. That URL string varies from provider to provider: every service publishes documentation with the URL, the credentials, and how to use it, and paid services ask for a password. Then a for loop went over the four countries one by one: for each country code, call the URL, check whether the request was successful, get the value, and publish it into a GDP data frame.

import requests
import pandas as pd

country_codes = ["US", "CN", "IN", "JP"]
api_url = "https://api.worldbank.org/v2/country/{}/indicator/NY.GDP.MKTP.CD?format=json"
gdp_rows = []

for code in country_codes:
    response = requests.get(api_url.format(code))
    if response.status_code == 200:
        value = response.json()[1][0]["value"]
        gdp_rows.append([code, value])

gdp_df = pd.DataFrame(gdp_rows, columns=["Country", "GDP"])

Worked example: tracing one loop iteration. Take the first country, the US. The loop formats the URL with the code "US", so requests.get asks the World Bank server for the US's GDP. The server answers with a response object; response.status_code is 200, the success code, so the check passes. The body of the response is a JSON structure; response.json()[1][0]["value"] digs into it and extracts the GDP figure — about 25 trillion. The pair ["US", 25_trillion] is appended to the growing list, and the loop moves to China, then India, then Japan. When the loop finishes, the four rows are wrapped in a data frame. Sense-check: one URL per country, one value per URL, four countries in, four rows out — the for loop guarantees every country is fetched exactly once and the status check guarantees a bad response does not silently enter the data.

Pitfalls.

  1. Not checking the status code. A failed request can return an empty or error structure; always check response.status_code == 200 (success) before extracting the value, exactly as the demo's loop does.
  2. Changing data structure between providers. Each API documents its own response format; the [1][0]["value"] path is World Bank-specific. Read the provider's documentation rather than assuming the same shape.
  3. Ignoring rate limits and credentials. Free tiers and paid APIs enforce limits; an API that asks for a password must receive it per the documentation, and excessive calls can get you blocked.
  4. Misreading the numbers — a figure without decimals can be misread by an order of magnitude; see the GDP reading below.

13.8.3 Reading the GDP Numbers

The API returned real-time GDP data for the four countries: the United States at about 25 trillion, China at about 17 trillion, India at about 3.4 trillion, and Japan at about 4.2 trillion. A quick check on those numbers: because the figures come without decimals, it is easy to misread them and think China has the biggest GDP. That is not right; China is number two, and the United States is still number one. India is around number five by GDP, as a cross-check from another source confirmed. The example stopped at fetching the data, but once the data frame is there, extending it to a chart is the same plotting code as in every other example.

The no-decimals trap (from the session). The World Bank returns whole numbers — 25 trillion shows as a long digit string, not as "25.0 trillion." When you scan the raw figures, China's 17-trillion figure can look bigger than the US's 25 trillion if the digit counts confuse you; the professor's warning: do not misread China as number one — the United States is still number one, China is number two. The lesson is a general one: when an API hands you a raw number, read the magnitude carefully — units and digit lengths — before drawing conclusions. India's GDP of about 3.4 trillion places it around number five globally, confirmed against a separate source.

Once the data is in a data frame, extending the demo to a chart is the same plotting code from every other example — pick the GDP column, pick the country labels, call plt.bar or plt.scatter, add the title and show.

13.8.4 Real-world: Finance and Economic Data at Your Fingertips

Real-world: this is the workflow behind live dashboards, where instead of a manually maintained Excel sheet the chart refreshes by calling an API. The same pattern applies to stock prices (Yahoo Finance, CNBC) and to macroeconomic data (World Bank), so one plotting skill covers very different data sources.

Recap: an API is a documented doorway to a data service — build the URL, requests.get(url), check success, extract the value, and collect the results in a data frame; from there, plotting is the same code as always. The URL and response shape change per provider; the pattern does not.

Real-world connection: live dashboards everywhere run on this pattern — a finance terminal pulls prices from Yahoo Finance's API, an economic portal refreshes GDP charts from the World Bank, a logistics dashboard queries weather APIs for route conditions. One skill — requests plus matplotlib — covers data sources as different as stock prices and national accounts, replacing the manually maintained Excel sheet with a chart that updates itself.

13.9 Geographic Plotting with Basemap

13.9.1 The Basemap Library

The hook: every chart so far lived on a flat rectangle of axes. But what if your data is tied to places — stores, storms, cities? matplotlib can draw maps too, with a library called basemap.

matplotlib can plot geographical data too, with a library called basemap, which is the geographic map plotting library. You pass parameters: the type of projection, the longitude and latitude ranges, meaning the min and max of those variables, and then the data variables. There are various projection types to choose from; these parameters are something you have to check synthetically for each use case.

What basemap needs, and why the parameters matter. Basemap draws a map as the background of a plot, so you must tell it which piece of the Earth's surface to draw:

  • Projection type — the method used to flatten the curved Earth onto a flat page. Different projections (e.g., the common cylindrical projection, or the polar-stereographic projection for polar regions) distort distance, area, or shape differently, so the choice depends on the use case.
  • Longitude and latitude ranges — the longitude (the east-west coordinate, in degrees) and latitude (the north-south coordinate, in degrees) bounds: the min and max of each variable tell basemap which geographic window to draw.
  • The data variables — the actual plotted values, positioned on the map by their coordinates.

These parameters are the kind of thing you check case by case — the reference documentation lists the available projections, and the right one depends on the region and the story the map must tell.

13.9.2 Demo and the Environment Snag

Worked example: the basemap call that draws a map. The demo's core call passes the projection and the coordinate window, then the data:

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

m = Basemap(projection="cyl", llcrnrlon=-130, llcrnrlat=20,
            urcrnrlon=-60, urcrnrlat=55)
m.drawcoastlines()
plt.show()

Reading the parameters: projection="cyl" picks a cylindrical projection (the standard rectangular world view), llcrnrlon and llcrnrlat give the lower-left corner of the map window (longitude , latitude ), and urcrnrlon and urcrnrlat give the upper-right corner (longitude , latitude ) — so the window covers roughly North America, from about to longitude and to latitude. Passing these longitude and latitude parameters is what created the map in the demo; the data variables would then be plotted on top of that map by their coordinates. Sense-check: min and max define the window, the projection defines the flattening, and the map appears between those bounds — change any range number and the visible map region changes.

In the demo, passing the longitude and latitude parameters created the map. The example itself was small, but with vast country-level data and many plots, the library has the potential to draw full geographic datasets. The demo had a technical snag worth knowing about: the night before, installing one particular library left the environment broken, because basemap expects that library. If the code fails, the fix is to repair the environment, which is exactly why it is worth keeping a clean, reproducible setup.

The environment snag (from the session). The demo itself is small — pass the projection, longitude and latitude bounds, then the data — but the session's setup broke the night before: installing one particular library damaged the environment because basemap depends on it. When the code failed, the fix was repairing the environment. The lesson is practical and durable: keep a clean, reproducible Python setup, record your package versions, and expect dependency friction when a library like basemap expects companion packages.

Pitfalls.

  1. Dependency breakage — basemap depends on companion libraries; installing one package can break another. Repair the environment (or recreate it) rather than patching around the symptom.
  2. Wrong projection for the region — a projection suited to mid-latitudes distorts polar data badly; check the options for each use case.
  3. Bounding-box mistakes — swapped longitude/latitude min and max values draw an empty or upside-down map; keep the ranges consistent.
  4. Expecting dashboard-level polish — basemap maps are capable but not as sophisticated out of the box as the world maps built into Power BI or Tableau (the professor's own comparison); treat it as the plotter, not the full GIS tool.

13.9.3 The Bigger Picture: These Libraries Are Powerful

These are not small libraries that only do simple mathematics. The same ecosystem handles statistics, standard deviation, and many models, including linear regression and classification, and it is known for dealing with very big data. That is why these libraries are so popular, and they keep getting more powerful.

Recap: basemap turns longitude and latitude parameters into a map background for your data; choose the projection and the coordinate window per use case, keep the environment clean, and remember the library is one member of a much larger, very powerful scientific Python ecosystem that also does statistics, machine learning, and big data.

Real-world connection: geographic plotting puts data on a map wherever location is the story — logistics companies plot delivery routes and hubs, retailers map stores and catchment areas, climate scientists overlay temperature readings on country-level grids. In the tools comparison running through this course, basemap is the programmatic counterpart to the built-in world maps of Power BI and Tableau — less polished by default, but scriptable, free, and part of the same Python stack that later handles the modeling.

13.11 Matplotlib's Documentation and Community

The hook: you have learned a dozen commands — but matplotlib ships with thousands. How do you find the right one when you need it? The official website is the starting point, and it is designed to be self-serve.

The matplotlib website is the starting point for learning. It lists the plot types it supports: scatter, bar, and everything we have seen, plus statistical distributions, violin plots, and 3D plots such as surfaces. Sometimes you have to literally see a surface to know it is possible. The site ships ready-made examples, including downloadable zip files, so you can start using them immediately. It is a very rich library with a very rich user guide, covering colors, sample styling, and each and every parameter with usage notes.

How to use the gallery (the self-learning pattern). The website's gallery is a page of ready-made example figures. The workflow the professor models: spot a chart you want → find its example in the gallery → download the zip or copy the code → run it → adapt the data to your own business case. The gallery doubles as a discovery tool: 3D surfaces, violin plots, and statistical distributions become visible possibilities only when you literally see them — sometimes you have to see a surface to know it is possible. The user guide backs every example up with parameter-by-parameter notes, so each example teaches the concept and the guide explains the controls.

The site also publishes downloadable zip files of the example collections, so you can start using them immediately rather than retyping code.

13.11.2 Colors: Names, Hex, and RGB

The color documentation is a good example of the depth: a color palette with ready-made soft colors, names like aqua and pink, plus the option of hex values and RGB values, and many more ways to specify colors. Whatever color-related parameter you need, it is documented.

Worked example: three ways to say the same color. The color documentation shows the palette of ready-made soft colors — type aqua or pink and the chart shows that exact color. The same color can also be given numerically:

Way to specify Example What it means
Named color color="aqua" One of the built-in palette names shown on the color page
Hex value color="#00FFFF" A six-digit hexadecimal code: red, green, and blue components in two hex digits each
RGB value color=(0.0, 1.0, 1.0) The same three components as decimals between 0 and 1

#00FFFF and (0.0, 1.0, 1.0) both mean "no red, full green, full blue" — the aqua/cyan color. Sense-check: the three forms describe the same color in different notations, and the documentation documents each one, so whatever color-related parameter you need, it is covered.

13.11.3 Free Tools and the Self-Learning Habit

All of this is free: Python is free, and Jupyter is free. The strong suggestion from the session is that if you see this adding value to your future career, keep doing it, at least the basics. The library expects some kind of prerequisite, Python itself, but it is a very good library to be part of learning. Just listening does not help; running the examples yourself is how the material sticks.

Exam note: the matplotlib gallery and user guide are study resources — learn the concept, then apply it. The website documents every plot type, ships downloadable examples, and documents every color form; the study advice is consistent with the whole session: just listening does not help — running the examples yourself is how the material sticks.

Recap: the official website is the self-learning hub — the plot-type list shows what is possible, the gallery ships ready-made examples to run and adapt, and the user guide documents every parameter, including all color forms (named, hex, RGB). Python and Jupyter are free; the prerequisite is Python itself; and the habit of running examples is what makes the library stick.

Real-world connection: the documentation-first habit is how working data professionals keep up with a library that grows monthly — a finance analyst looking for a candlestick chart, a healthcare team building a violin plot, or an engineer creating a 3D surface all start the same way: find the gallery example, run it, adapt it. The community is the second half of the story: a vast user base means answers, examples, and extensions exist for nearly every problem, which is precisely why the professor calls the ecosystem the reason these libraries keep winning.

Exam Guidance Summary

The session carried no exam-format announcements, but the recurring study advice is clear and consistent:

  • Practice hands-on. The repeated message is that just listening will not help; run every example yourself.
  • Use the free tools. Anaconda, Jupyter, and Google Colab, all of which are free to set up.
  • Work the assignment. The assignment covering these plotting skills is available on the course portal, and working through it helps you brush up on what we are doing.
  • Self-learning is part of the material. matplotlib's command set is an ocean, so learn how to learn: the gallery gives ready-made examples, and the user guide documents every parameter. Learn the concept, then apply it to your business case.
  • High-emphasis facts worth remembering from this session:
  • The subplot call takes row, column, and sequence.
  • plt.plot draws lines while plt.scatter draws points.
  • plt.bar is vertical and plt.barh is horizontal.
  • A pie chart starts at the X axis and fills anticlockwise; each slice angle is proportional to its value.
  • A histogram's bars are counts per bin; random data without a seed changes on every run.
  • The three data-source patterns (database, CSV, web API) all converge on the same plotting calls once the data is in a data frame.

Key Industry Applications

  • Real-world: Stock market analysis. Live close-price time series pulled straight from a MySQL database, price-versus-volume scatter plots, and multi-year trend charts, demoed with ITC and State Bank of India data.
  • Real-world: Finance data APIs. Yahoo Finance and CNBC provide APIs for market data, typically paid with limited free usage; Moneycontrol's API availability was noted for checking.
  • Real-world: Economic data. The World Bank API returns real-time GDP data for any country, enabling country-by-country comparisons (US 25 trillion, China 17 trillion, India 3.4 trillion, Japan 4.2 trillion — the United States, not China, is number one).
  • Real-world: BI tool comparison. Tableau and Power BI are drag-and-drop; Python gives programmatic control with per-plot precision, at the cost of needing coding knowledge.
  • Real-world: Data science and machine learning. TensorFlow, PyTorch, and scikit-learn are the frameworks for deep learning, machine learning, and neural networks; matplotlib is expected to integrate ever more closely with them.
  • Real-world: Web dashboards. WebGL and modern web technologies will carry matplotlib into web pages and dashboards, with zooming, brushing, and dragging.
  • Real-world: Explainable AI and regulation. The EU AI Act puts heavy penalties on AI and machine learning solutions that do not explain their numbers; business users increasingly demand to know how a predicted number is derived.
  • Real-world: Domain-specific toolkits. Expect specialized matplotlib toolkits for heavy engineering, finance, medical, and industrial automation domains.

DVI Lecture 13 notes · Matplotlib: Advanced Plot Types and Real Data Sources

Data Visualization and Interpretation· postgraduate· 2026-08-11

Sections Breakdown

113.1 Recap: Where We Left Off

The session wraps up matplotlib: Seaborn and Bokeh build on it next; the recap revisits subplot parameters (row, column, sequence), the position formula, and interactive mode, which draws each plot immediately instead of waiting for the final command.

213.2 Scatter Plots

plt.scatter(x, y) draws one dot per (x, y) pair from two aligned arrays; plt.plot connects the same points with a line. Scatter reveals relationships between two measurements and must never be read as causation.

313.3 Bar Charts

plt.bar draws vertical bars whose heights are the Y values, with X as labels; plt.barh flips the same values horizontal. color, width, and height are per-plot parameters; Python's programmatic control beats drag-and-drop templates for per-element precision.

413.4 Histograms

A histogram counts how many values fall into each bin and draws one bar per bin. The demo generated 250 random values from a normal distribution with mean 170 and standard deviation 10, producing a bell-shaped histogram peaking at 170 that changes every run because no seed is fixed.

513.5 Pie Charts

A pie chart starts at the X axis (zero degrees) and fills anticlockwise; each slice angle is proportional to its value: theta_i = v_i / sum(v_j) x 360 degrees. Labels pair with values by position; startangle, explode, shadow, colors, legend, and title are optional decorations.

613.6 Plotting Data from a Database (MySQL)

The database-to-plot workflow: import matplotlib and the MySQL connector, pass credentials, build a SQL string, create a cursor, execute, fetch rows, put them in a pandas data frame, then plot with the usual column-based plt.plot. Changing only the WHERE clause changes the chart.

713.7 Reading Data from CSV Files

pd.read_csv('filename.csv') reads a CSV into a data frame in one line, replacing the database connector steps; plotting from the data frame is the same column-based code. Scatter needs numeric columns; a date column means a line plot. Forgetting to re-upload an edited CSV shows stale data.

813.8 Reading Data from the Web (APIs)

APIs let code fetch data directly from services (Yahoo Finance, CNBC, World Bank): build the URL, requests.get(url), check the status code, extract the value, collect into a data frame. The World Bank demo returned US 25T, China 17T, India 3.4T, Japan 4.2T; no decimals make China easy to misread as number one.

913.9 Geographic Plotting with Basemap

Basemap plots geographic data by passing the projection type, longitude and latitude ranges (min and max), and data variables. The demo created a map from these parameters; a broken environment from a library install caused the demo snag, teaching the value of a clean reproducible setup.

1013.10 Future Trends in Matplotlib

Six projected trends: deeper integration with data science frameworks (TensorFlow, PyTorch, scikit-learn), web technologies and interactivity (WebGL, zoom, brush, drag), accessibility narrowing the gap with commercial tools, domain-specific toolkits, explainable AI under the EU AI Act, and a single integrated environment.

1113.11 Matplotlib's Documentation and Community

The matplotlib website is the self-learning hub: it lists all plot types (including statistical and 3D), ships downloadable ready-made examples, and documents every parameter, including the color forms (named, hex, RGB). Python and Jupyter are free; running examples yourself is how the material sticks.

12Exam Guidance Summary

No exam-format announcements, but consistent study advice: practice hands-on with free tools (Anaconda, Jupyter, Google Colab), work the assignment, embrace self-learning (gallery + user guide), and remember the high-emphasis facts: subplot row-column-sequence, plot vs scatter, bar vs barh, pie chart X-axis anticlockwise start, and the three data-source patterns converging on the same plotting calls.

13Key Industry Applications

Real-world applications: stock market analysis from MySQL (ITC, SBI), finance data APIs (Yahoo Finance, CNBC, Moneycontrol), World Bank GDP data, BI tool comparison, data science frameworks integration, web dashboards with WebGL interactivity, explainable AI under the EU AI Act, and domain-specific toolkits.

Postgraduate students in Data Visualization and Interpretation

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

Recap: Where We Left Off

Must-know: The subplot call takes row, column, and sequence in that order, with position counting left to right, top to bottom; interactive mode makes each plot appear immediately rather than at the final show() command.

⚠️ Top pitfall: Reversing rows and columns in subplot, or being surprised when plots appear early because interactive mode is on.

Self-check: In a 2x3 subplot grid, which cell does sequence number 4 occupy?

Connects to: 13.2 Scatter Plots

Scatter Plots

Must-know: plt.scatter draws one point per (x_i, y_i) pair; plt.plot draws the same pairs joined by a line. Arrays must be equal in length.

⚠️ Top pitfall: Mismatched array lengths; reading causation into a scatter pattern; using plot when scatter is meant (or vice versa).

Self-check: With x = [2, 4, 6, 8] and y = [10, 14, 16, 20], how many dots does plt.scatter(x, y) draw and where?

Connects to: 13.3 Bar Charts

Bar Charts

Must-know: plt.bar makes vertical bars with value as height; plt.barh makes horizontal bars with value as width; both take labels in X and values in Y; color can be one value or a per-bar list.

⚠️ Top pitfall: Color list shorter than the number of bars; width so large the bars overlap; using vertical bars with long category names.

Self-check: How would you draw the same four values as horizontal bars with per-bar colors?

Connects to: 13.4 Histograms

Histograms

Must-know: Histograms show distribution: plt.hist counts values per bin and draws bars. Random data with mean 170 and standard deviation 10 was drawn from a normal distribution X ~ N(170, 10); the standard deviation is 10 (not the variance).

⚠️ Top pitfall: Treating the given standard deviation 10 as the variance (variance is the square, 100); misreading bar height as a data value instead of a bin count.

Self-check: What fraction of the 250 normal values fall between 160 and 180, and why?

Connects to: 13.5 Pie Charts

Pie Charts

Must-know: The pie starts at the X axis and fills anticlockwise; the slice angle is the value's share of the total times 360 degrees; labels match values in order.

⚠️ Top pitfall: Passing labels in the wrong order, so the wrong name lands on each slice; values that do not sum to the whole produce an incomplete pie.

Self-check: For values 35, 25, 25, 15, what is the angle of the first slice?

Connects to: 13.4 Histograms, 13.6 Plotting Data from a Database (MySQL)

Plotting Data from a Database (MySQL)

Must-know: The connection pattern: import connector, pass credentials, build SQL string, cursor.execute, fetch, pandas data frame, then the usual plot. The database only changes the first few steps; plotting is unchanged once data is in a data frame.

⚠️ Top pitfall: Changing the query but not re-running the whole notebook (cursor is closed); YYMMDD date literal format mistakes.

Self-check: After changing a WHERE clause in the SQL string, why must you run all cells from connection to plot again?

Connects to: 13.7 Reading Data from CSV Files

Reading Data from CSV Files

Must-know: pd.read_csv reads a file into a data frame in one line; column selection then feeds the usual plot or scatter. A date column forces a line plot, not a scatter. Stale plots usually mean the edited CSV was never re-uploaded.

⚠️ Top pitfall: Editing the CSV locally but forgetting to upload it, so the plot shows old data; column name mismatches after changing files.

Self-check: Why can't you scatter-plot a date column, and what command replaces it?

Connects to: 13.6 Plotting Data from a Database (MySQL), 13.8 Reading Data from the Web (APIs)

Reading Data from the Web (APIs)

Must-know: The web-data pattern: build URL, requests.get(url), check success (status 200), extract value, publish into a data frame, then plot as usual. GDP figures without decimals mislead: US 25T is number one, China 17T number two.

⚠️ Top pitfall: Not checking the status code before extracting; misreading whole-number GDP figures (China looks like number one, but the US is).

Self-check: Why must the for loop check response.status_code before extracting the GDP value?

Connects to: 13.6 Plotting Data from a Database (MySQL), 13.7 Reading Data from CSV Files

Geographic Plotting with Basemap

Must-know: Basemap draws maps from projection type, longitude/latitude min-max ranges, and data variables; parameters are checked per use case. Dependency installs can break the environment basemap relies on, so keep a clean reproducible setup.

⚠️ Top pitfall: Environment breakage from installing a library basemap depends on; choosing the wrong projection for the region.

Self-check: What three kinds of parameters does basemap need to draw a map?

Connects to: 13.8 Reading Data from the Web (APIs)

Future Trends in Matplotlib

Must-know: Explainable AI: models can no longer output a number from a black box; business users demand to know how a prediction is derived, and the EU AI Act (passed the month before the session) imposes heavy penalties on solutions that do not explain. Matplotlib and every AI library must align with this.

⚠️ Top pitfall: Presenting a model output without explaining how it is derived; reading future-trend claims as features available in the current version.

Self-check: What is explainable AI, and which regulation now enforces it in the EU?

Connects to: 13.11 Matplotlib's Documentation and Community

Matplotlib's Documentation and Community

Must-know: The matplotlib gallery and user guide are study resources: learn the concept, then apply it to your business case. The gallery shows what is possible, the guide documents every parameter including named/hex/RGB colors.

⚠️ Top pitfall: Reading examples without running them; just listening does not help — practice is essential.

Self-check: What three ways does matplotlib documentation give to specify the same color?

Connects to: 13.5 Pie Charts

Exam Guidance Summary

Must-know: Practice hands-on: just listening does not help. High-emphasis facts: subplot takes row, column, sequence; plot draws lines, scatter draws points; bar is vertical, barh horizontal; pie starts at the X axis and fills anticlockwise; database/CSV/web data all converge to the same plotting calls in a data frame.

⚠️ Top pitfall: Studying by listening alone instead of running the examples in a free tool.

Self-check: What are the high-emphasis facts to remember from this session?

Key Industry Applications

Must-know: The plotting skills converge on three data-source patterns (database, CSV, web API) that power live dashboards; explainable AI and the EU AI Act push every AI solution to explain its numbers.

⚠️ Top pitfall: Presenting model output as a number from a black box without explaining how it is derived.

Self-check: Which data sources can feed the same plotting code once data is in a data frame?

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.