You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor Jupyter Book to use literalinclude for Python code
- Replaced all inline Python code blocks with literalinclude directives
- Now references external .py files from ../../python/ directory
- Benefits:
- Single source of truth for all Python code
- Code changes automatically reflected in the book
- Consistent with LaTeX approach using \pyfile{}
- Easier testing and maintenance
- Updated all 10 chapters (100+ code blocks converted)
- Successfully tested build with literalinclude working properly
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: jupyterbook/chapter1/index.md
+14-66Lines changed: 14 additions & 66 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,21 +4,14 @@ Matplotlib offers two interfaces: a MATLAB-style interface and the more cumberso
4
4
5
5
The MATLAB-style interface looks like the following.
6
6
7
-
```python
8
-
import matplotlib.pyplot as plt
9
-
x =1,0
10
-
y =0,1
11
-
12
-
plt.plot(x,y)
13
-
plt.title("My Plot")
7
+
```{literalinclude} ../../python/matlab-plot.py
8
+
:language: python
14
9
```
15
10
16
11
The object-oriented interface looks like this.
17
12
18
-
```python
19
-
fig, ax = plt.figure(), plt.axes()
20
-
ax.plot(x,y)
21
-
ax.set_title("My Plot")
13
+
```{literalinclude} ../../python/oop-plot.py
14
+
:language: python
22
15
```
23
16
24
17
There is no such thing as a free lunch, so you will observe this interface requires more code to do the same exact thing. Its virtues will be more apparent later. Object-oriented programming (OOP) also requires some new vocabulary. OOP might be contrasted with procedural programming as another common method of programming. In procedural programming, the MATLAB-style interface being an example, the data and code are separate and the programmer creates procedures that operate on the program's data. OOP instead focuses on the creation of *objects* which encapsulate both data and procedures.
@@ -29,10 +22,8 @@ An object's data are called its *attributes* and the procedures or functions are
29
22
30
23
A plot requires a figure object and an axes object, typically defined as `fig` and `ax`. The figure object is the top level container. In many cases like in the above, you'll define it at the beginning of your code and never need to reference it again, as plotting is usually done with axes methods. A commonly used figure parameter is `figsize`, to which you can pass a sequence to alter the size of the figure. Both the figure and axes objects have a `facecolor` parameter which might help to illustrate the difference between the axes and figure.
31
24
32
-
```python
33
-
fig = plt.figure(figsize= (2,3),
34
-
facecolor='gray')
35
-
ax = plt.axes(facecolor='lightyellow')
25
+
```{literalinclude} ../../python/figparams.py
26
+
:language: python
36
27
```
37
28
38
29

@@ -41,16 +32,8 @@ The axes object, named `ax` by convention, gets more use in most programs. In pl
41
32
42
33
This wishful coding won't take you everywhere though. For example, `plt.xlim()` is replaced by `ax.set_xlim()` to set the x-axis view limits. To modify the title, `plt.title()` is replaced with `ax.set_title()` and there is `ax.get_title()` simply to get the title. The axes object also happens to have a `title` attribute, which is only used to access the title, similar to the `get_title()` method. Many matplotlib methods can be classified as *getters* or *setters* like for these title methods. The plot method and its logic is different. Later calls of `ax.plot()` don't overwrite earlier calls and there is not the same getter and setter form. There's a `plot()` method but no single `plot` attribute being mutated. Whatever has been plotted can be retrieved, or gotten (getter'd?), but it's more complicated and rarely necessary. Use the code below to see what happens with two calls of `plot()` and two calls of `set_title()`. The second print statement demonstrates that the second call of `set_title()` overwrites the title attribute, but a second plot does not nullify the first.
43
34
44
-
```python
45
-
x = np.linspace(0,1,2)
46
-
fig, ax = plt.figure(figsize= (8,4)), plt.axes()
47
-
ax.plot(x, x)
48
-
ax.plot(x, 1- x)
49
-
ax.set_title("My Chart")
50
-
print(ax.title)
51
-
print(ax.get_title()) # Similar to above line
52
-
ax.set_title("My Wholesome Chart")
53
-
print(ax.get_title()) # long
35
+
```{literalinclude} ../../python/gettersetter.py
36
+
:language: python
54
37
```
55
38
56
39

@@ -63,59 +46,24 @@ Axes methods `set_xlim()` and `get_xlim()` behave just like `set_title()` and `g
63
46
64
47
You can also mix the interfaces. Use `plt.gca()` to *g*et the *c*urrent *a*xis. Use `plt.gcf()` to *g*et the *c*urrent *f*igure.
65
48
66
-
```python
67
-
x = np.linspace(0,1,2)
68
-
plt.plot(x,x)
69
-
plt.title("My Chart")
70
-
71
-
ax = plt.gca()
72
-
print(ax.title)
73
-
74
-
ax.plot(x, 1- x)
75
-
ax.set_title('My Wholesome Chart')
76
-
print(ax.title)
49
+
```{literalinclude} ../../python/chart.py
50
+
:language: python
77
51
```
78
52
79
53

80
54
81
55
In the above, we started with MATLAB and then converted to object-oriented. We can also go in the opposite direction, though it's not always ideal, especially when working with subplots. Below, we start with our figure and axes objects, and then revert back to the MATLAB style with the `axvline()` functions (producing vertical lines across the axes), toggling off the axis lines and labels, and then saving the figure. This graph would appear unchanged if you replaced `plt.axvline()` with `ax.axvline()`, `plt.axis()` with `ax.axis()`, and `fig.savefig()` would do the same as `plt.savefig()`.
82
56
83
-
```python
84
-
# OOP Start
85
-
fig, ax = plt.figure(figsize= (8,5)), plt.axes()
86
-
87
-
x = np.linspace(0,100,2)
88
-
ax.plot(x, x, color='gray')
89
-
90
-
ax.set_xlim([0,100])
91
-
ax.set_ylim([0,100])
92
-
93
-
# Back to pyplot functions
94
-
for i inrange(101):
95
-
plt.axvline(i,0, i /100, color='C'+str(i))
96
-
plt.axvline(i, i/100, 1, color='C'+str(i+5))
97
-
98
-
plt.axis('off')
99
-
plt.savefig('colorful.pdf')
57
+
```{literalinclude} ../../python/colorful.py
58
+
:language: python
100
59
```
101
60
102
61

103
62
104
63
Matplotlib is also integrated into pandas, with a `plot()` method for both Series and DataFrame objects, among other functionalities. There is excellent documentation [available](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html). These plots can be mixed with the object-oriented interface. You can use a plot method and specify the appropriate axes object as an argument. Below we import the iris dataset and make a boxplot with a mix of axes methods and then pyplot functions.
0 commit comments