我正在阅读《Python 速成课程》这本书,我正在尝试使用 pygal 来可视化随机游走。(练习 15.10)。
这是我的代码:
from random import choice
class RandomWalk():
"""A class to generate random walks."""
def __init__(self, num_points=500):
"""Initialize attributes of a walk."""
self.num_points = num_points
# All walks start at (0, 0).
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):
"""Calculate all the points in the walk."""
# Keep taking steps until the walk reaches the desired length.
while len(self.x_values) < self.num_points:
# Decide which direction to go and how far to go in that direction.
x_step = self.get_step()
y_step = self.get_step()
# Reject moves that go nowhere.
if x_step == 0 and y_step == 0:
continue
# Calculate the next x and y values.
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)
#Visualizing with Pygal
import pygal
while True:
rw = RandomWalk()
rw.fill_walk()
xy_chart=pygal.XY()
xy_chart.title = 'Random Walk'
rwValues=list(zip(rw.x_values,rw.y_values))
xy_chart.add('rw',rwValues)
xy_chart.render_to_file('rw_visual.svg')
随机游走代码的逻辑很好,但是我似乎无法理解如何用 pygal 将其可视化。每当我运行代码(在 Jupyter 笔记本上)时,笔记本都不会处理它。我尝试用 matplotlib 对其进行可视化,一切都很好。如果有人能解释我做错了什么那就太好了。使用 matplotib 代码进行可视化是:
import matplotlib.pyplot as plt
# Keep making new walks, as long as the program is active.
while True:
rw = RandomWalk()
rw.fill_walk()
plt.figure(figsize=(10, 10))
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.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk? (y/n): ")
if keep_running == 'n':
break
运行得很好。
这是因为 Jupyter 默认情况下无法在输出单元上渲染
SVG
图像,因此您需要调整代码,以便 IPython
控制台可以读取它。您可以执行以下操作:
from IPython.display import HTML, display, SVG
import pygal
while True:
rw = RandomWalk()
rw.fill_walk()
xy_chart = pygal.XY()
xy_chart.title = 'Random Walk'
rwValues = list(zip(rw.x_values, rw.y_values))
xy_chart.add('rw', rwValues)
keep_running = input("Make another walk? (y/n): ")
if keep_running == 'n':
display({'image/svg+xml': xy_chart.render()}, raw=True)
# OR
xy_chart.render_in_browser()
# OR
display(SVG(xy_chart.render(disable_xml_declaration=True)))
break
我现在只写了不到 3 个月的代码,但我认为你没有正确理解这个问题。
它说在 Ploty 上使用绘图随机游走(离线),我没有使用 pygal,所以我可能会回答一个没人问的问题,但无论如何我都会这样做。
由于书中的问题含糊不清,我将向您展示我是如何做到的。
from random import choice
from plotly.graph_objs import*
from plotly import offline
class RandomWalk:
'''Generate random walks'''
def __init__(self,points=5000):
self.points = points
#staring point is 0
self.x_values =[0]
self.y_values = [0]
def fill_walk(self):
'''calculating all of the points in the walk'''
while len(self.x_values) < self.points:
x_direction = choice([-1, 1])
x_distance = choice([0, 3])
x_step = x_direction * x_distance
y_direction = choice([-1, 1])
y_distance = choice([0, 3])
y_step = y_direction * y_distance
# reject all moves that go nowhere
if x_step == 0 and y_step == 0:
continue
x = self.x_values[-1] + x_step
y = self.y_values[-1] + y_step
self.x_values.append(x)
self.y_values.append(y)
rw = RandomWalk()
rw.fill_walk()
xa = list(range(rw.points))
frequencies = []
for a_number in (range(1,rw.points)):
frequency = rw.x_values.count(a_number)
frequencies.append(frequency)
data = [Bar(x=xa,y=frequencies)]
my_layout = Layout(title="We'll see",xaxis={'title':'X'},yaxis={'title':'Y'})
offline.plot({'data': data,'layout':my_layout},filename='my.html')
显示 y 值变化(频率 = rw.y_values.count(a_number)
我对代码感到抱歉,并且缺乏评论,这是我第一次发帖,但随着时间的推移,我会变得更好
骰子:
from random import randint
class Die:
def __init__(self,num_sides = 0):
self.num_side = num_sides
def roll(self):
return randint(1,self.num_side)
使用 matplot lib 进行骰子可视化:
import matplotlib.pyplot as plt
from die import Die
die1 = Die(6)
die2 = Die(8)
result = []
frequency = []
max_num = (die1.num_side+die2.num_side)
for r in range(1,1000):
result.append(die1.roll()+ die2.roll())
for value in range(2, max_num+1):
frequency.append(result.append(value))
# its make me cunfuse but result loop make 1012 point instade of 999?
# i dont know whay but below calculation is the way come to my mind to
# make sure both b in same size to can use scatter
x_value = list (range(1,len(result)+1))
plt.style.use("bmh")
fig,ax = plt.subplots()
#ax.plot(result,c=(0.34,0.67,0.55),linewidth=3)
ax.scatter(x_value,result,c=result,cmap=plt.cm.Reds,
edgecolor="none",s=3)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
随机游走:
from random import choice
class RandomWalk:
def __init__(self,num_points=5000):
self.num_poins = num_points
self.x_value = [0]
self.y_value = [0]
def fill_walk(self):
while len(self.x_value) < self.num_poins:
x_direction = choice([1,-1])
x_distance = choice([0,1,2,3,4])
x_point = x_direction* x_distance
y_direction = choice([1,-1])
y_distance = choice([0,1,2,3,4])
y_point = y_direction* y_distance
if x_point and y_point == 0:
continue
x = self.x_value[-1] + x_point
y = self.y_value[-1] + y_point
self.x_value.append(x)
self.y_value.append(y)
用plotly可视化随机游走:
from plotly.graph_objects import Bar , Layout
from plotly import offline
from random_walk import RandomWalk
rw = RandomWalk()
rw.fill_walk()
x_val
## Heading ##
ue = rw.x_value data = [Bar(x=x_val
ue,y=rw.y_value)]
x_value_config ={"title":"x value"}
y_value_config ={'title':"y value"}
my_layout = Layout(title="showing random walk",xaxis=x_value_config,
yaxis=y_value_config)
offline.plot({'data':data,'layout':my_layout},filename='rw.html')