Python Programming: Getting Started to Practice Chapter 15


I read the second edition of this book. In the section on “Hiding axes” of this chapter, the hiding of axes reads as follows:

plt.axes().get_xaxis().set_visible(False) 
plt.axes().get_yaxis().set_visible(False)
Copy the code

However, even though I copied, copied and pasted the sentence in the textbook, there was no plot content in pyCharm’s virtual environment and VS Code’s environment, but a very strange coordinate chart.

The same code can be run in Jupyter Notebook (shown as a borderless image) but warning:

/ SRV/conda/envs/notebook/lib/python3.6 / site – packages/ipykernel_launcher. Py: 45: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.

Check on StackOverflow and it looks like someone said:

plt.gca().axes.get_xaxis().set_visible(False)
plt.gca().axes.get_yaxis().set_visible(False)
Copy the code

After Baidu, discovery also somebody has same problem. I don’t know if it is due to the updated version.


15-1 cubed: The third power of a number is called its cubed. Draw a graph showing the cubic values of the first five integers and another graph showing the cubic values of the first 5000 integers.

We saw lambda and map functions before, so it’s good to use them.

num = list(map(lambda x: x**3.list(range(4))))
plt.plot(num)
plt.show()
Copy the code

15-2 Color cube: Specify the color mapping for the cube you drew earlier.

The textbook uses list parsing, which I haven’t used for a long time.

num = list(range(1.5001))
cubic = [x**3 for x in num]

plt.scatter(num, cubic, c=cubic, cmap = plt.cm.Reds, s=10)
plt.title("15-2")
plt.xlabel("value")
plt.ylabel("cubic value")
plt.show()
Copy the code

15-3 Molecular motion: modify rw_visual. Py and replace plt.scatter() with plt.plot(). To simulate the path of pollen on the surface of a droplet, pass rw.x_values and rw.y_values to plt.plot() and specify the linewidth of the argument. Use 5000 points instead of 50000 points.

import matplotlib.pyplot as plt
from random import choice


class RandomWalk() :
    def __init__(self, num_points=5000) :
        self.num_points = num_points

        self.x_values = [0]
        self.y_values = [0]

    def fill_walk(self) :
        while len(self.x_values) < self.num_points:
            x_direction = choice([-1.1])
            x_distance = choice([0.1.2.3.4])
            x_step = x_direction * x_distance

            y_direction = choice([-1.1])
            y_distance = choice([0.1.2.3.4])
            y_step = y_direction * y_distance

            if x_step == 0 and y_step == 0:
                continue

            next_x = self.x_values[-1] + x_step
            next_y = self.y_values[-1] + y_step

            self.x_values.append(next_x)
            self.y_values.append(next_y)


rw = RandomWalk()
rw.fill_walk()

point_numbers = list(range(rw.num_points))
plt.plot(rw.x_values, rw.y_values, linewidth=1)

plt.scatter(0.0, c='green', edgecolors='none', s=100)
plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
            s=100)

plt.gca().axes.get_xaxis().set_visible(False)
plt.gca().axes.get_yaxis().set_visible(False)

plt.show()
Copy the code

15-4 improved RandomWalk: in the class RandomWalk, x_step and y_step are generated according to the same conditions: randomly selecting directions from the list [1, -1] and randomly selecting distances from the list [0, 1, 2, 3, 4]. Modify the values in these lists to see what happens to random walk paths. Try using a longer distance selection list, such as 0 to 8; Or remove -1 from the x – or y-direction list.

slightly

15-5 Refactoring: The method fill_walk() is long. Create a new method called get_step() that determines the distance and direction of each walk and calculates how the walk will move. Then, get_step() is called twice in fill_walk() :

x_step = get_step() 
y_step = get_step() 
Copy the code

With this refactoring, you can reduce the size of fill_walk(), making the method easier to read and understand.

import matplotlib.pyplot as plt
from random import choice


class RandomWalk() :
    def __init__(self, num_points=5000) :
        self.num_points = num_points

        self.x_values = [0]
        self.y_values = [0]

    def get_step(self) :
        direction = choice([-1.1])
        distance = choice([0.1.2.3.4])
        step = distance * direction
        return step

    def fill_walk(self) :
        while len(self.x_values) < self.num_points:
            x_step = self.get_step()
            y_step = self.get_step()

            if x_step == 0 and y_step == 0:
                continue

            next_x = self.x_values[-1] + x_step
            next_y = self.y_values[-1] + y_step

            self.x_values.append(next_x)
            self.y_values.append(next_y)


rw = RandomWalk()
rw.fill_walk()

point_numbers = list(range(rw.num_points))
plt.plot(rw.x_values, rw.y_values, linewidth=1)

plt.scatter(0.0, c='green', edgecolors='none', s=100)
plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
            s=100)

plt.gca().axes.get_xaxis().set_visible(False)
plt.gca().axes.get_yaxis().set_visible(False)

plt.show()
Copy the code

15-6 Automatic generation of labels: Modify die. Py and dice_visual. Py to replace the list used to set hiST.x_labels with a loop that automatically generates such a list. If you’re familiar with list parsing, try replacing the other for loops in die_visual. Py and dice_visual. Py with list parsing.

Original list:

hist.x_labels = ['2', '3', '4', '5', '6','7', '8', '9', '10', '11', '12']
Copy the code

Continue with lambda:

hist.x_labels = list(map(lambda x : str(x), list(range(2.13))))
Copy the code

For list parsing:

hist.x_labels = [str(x) for x in range(2.13)]
Copy the code

15-7 Two D8 dice: Please simulate the result of rolling two 8-sided dice 1000 times simultaneously. Gradually increase the number of dice rolls until the system becomes overwhelmed.

from random import randint
import matplotlib.pyplot as plt


class Die() :
    def __init__(self, num_sides) :
        self.num_sides = num_sides

    def roll(self) :
        return randint(1, self.num_sides)


d8_1 = Die(8)
d8_2 = Die(8)

results = []

for roll_num in range(1000):
    result = d8_1.roll() + d8_2.roll()
    results.append(result)

print(results)

plt.hist(results,
         bins=[x for x in range(2, d8_1.num_sides + d8_2.num_sides + 1 + 1)],
         rwidth=0.8)
plt.title("Results of rolling 2 d8 dice")
plt.xlabel("Value")
plt.ylabel("frequency")
plt.show()
Copy the code

Remember that plt.hist seems to be able to generate histograms directly. But bins do take a tour of the place this time to see documentation, which is as follows:

bins: int or sequence or str, default: rcParams[“hist.bins”] (default: 10)

  • If bins is an integer, it defines the number of equal-width bins in the range.

  • If bins is a sequence, it defines the bin edges, including the left edge of the first bin and the right edge of the last bin; in this case, bins may be unequally spaced. All but the last (righthand-most) bin is half-open. In other words, if bins is:[1, 2, 3, 4]then the first bin is [1, 2)(including 1, but excluding 2) and the second [2, 3). The last bin, however, is[3, 4], which includes 4.

If bins are a list [1, 2, 3, 4], then they are inclusive: the first bin contains 1 and no 2, the second bin contains 2 and no 3, but the last bin contains both the preceding and subsequent values, i.e. the last bin contains 3 as well as 4.

Range () should be (2,16) in parentheses. But the range doesn’t include the number to the right of the parentheses, so you have to add one first to include the number to the right (16), and then you have to add one more to separate the last bin or the last bin will contain both 15 and 16.

If plt.bar() is used:

from random import randint
import matplotlib.pyplot as plt


class Die() :
    def __init__(self, num_sides) :
        self.num_sides = num_sides

    def roll(self) :
        return randint(1, self.num_sides)


d8_1 = Die(8)
d8_2 = Die(8)

results = []

for roll_num in range(1000):
    result = d8_1.roll() + d8_2.roll()
    results.append(result)


plt.hist(results,
         bins=[x for x in range(2, d8_1.num_sides + d8_2.num_sides + 1 + 1)],
         rwidth=0.8)
plt.title("plt.hist plot")
plt.xlabel("Value")
plt.ylabel("frequency")
plt.savefig("hist.png")

frequencies = []
max_results = d8_1.num_sides + d8_2.num_sides
for value in range(2, max_results + 1):
    frequency = results.count(value)
    frequencies.append(frequency)

plt.figure(figsize=(8.6))  # width:20, height:3
plt.bar(list(range(2, max_results+1)), frequencies, width = 0.7 )
plt.title("plt.bar plot")
plt.xlabel("Value")
plt.ylabel("frequency")

plt.savefig("bar.png")
plt.show()
Copy the code

15-8 Roll three dice simultaneously: If you roll three D6 dice simultaneously, the minimum possible roll is 3 and the maximum is 18. Please visualize the result of rolling three D6 dice simultaneously.

slightly

15-9 Multiplying the numbers: When rolling two dice at the same time, it is common to add their numbers. Visualize the result of multiplying the numbers of two dice.

slightly

15-10 Practice using the two libraries introduced in this chapter: try using Matplotlib to simulate dice rolling through visualization, and Try using Pygal to simulate random walks through visualization.

from random import choice
import pygal


class RandomWalk() :

    def __init__(self, num_points=5000) :
        self.num_points = num_points

        self.x_values = [0]
        self.y_values = [0]

    def get_step(self) :
        direction = choice([1, -1])
        distance = choice([0.1.2.3.4])
        step = direction * distance
        return step

    def fill_walk(self) :

        while len(self.x_values) < self.num_points:
            x_step = self.get_step()
            y_step = self.get_step()

            if x_step == 0 and y_step == 0:
                continue

            next_x = self.x_values[-1] + x_step
            next_y = self.y_values[-1] + y_step

            self.x_values.append(next_x)
            self.y_values.append(next_y)


rw = RandomWalk()
rw.fill_walk()
xy_chart = pygal.XY()
xy_chart.title = 'Random Walk'
Zip to form a list of tuples
rwValues = list(zip(rw.x_values, rw.y_values))
xy_chart.add('rw', rwValues)
xy_chart.render_to_file('rw_visual.svg')
Copy the code