Python利用随机函数生成变化图形详解

Dylan
Dylan
发布时间:2026-10-15 | 4人浏览过
原创

本文详解如何利用Python随机函数优化随机漫步程序。通过提取公共乘法逻辑简化代码,并设计New_case类动态生成指定数量的实例。每个实例拥有随机移动次数,利用字典映射颜色与实例ID,最终批量绘制不同颜色的散点图,实现输入一个参数即可自动生成多组对比图形。

问题背景与优化目标

针对上一篇内容末尾提出的三个遗留问题,我们逐一进行分析和解决。

第一,评估现有程序是否存在优化空间,特别是功能重复的部分。

第二,原代码中创建三个实例需要三条语句,能否封装为一个函数,仅接收一个整数n作为输入,自动创建n个实例?同时,每个实例的num_times(移动次数)应随机生成,且当n较大时,num_times的值应相应较小。

第三,在实现上述功能后,程序运行只需输入一个参数(即创建实例的个数),即可自动计算并生成对应的num_times,分别调用相关函数生成对应的图表。

答案是肯定的。在Rand_moving()类中,计算每一步的方向和移动位置时,都使用了一个相同的乘法公式。

x_direction = choice([1,-1])       #x的移动方向,1向上,0不变,-1向下
            x_distance = choice([0,1,2,3,4,5]) #x的每次移动的像素,
            x_step = x_direction*x_distance    #移动方向乘以移动距离,以确定沿x移动的距离
            
            y_direction =  choice([1,-1])      #y的移动方向,1向上,0不变,-1向下
            y_distance = choice([0,1,2,3,4,5]) #y的每次移动的像素,
            y_step = y_direction*y_distance    #移动方向乘以移动距离,以确定沿y移动的距离

因此,我们可以将该计算方法提取出来,形成可直接调用的独立方法。至于问题2和3,逻辑上也是完全可以实现的。

代码重构:提取移动步长计算方法

第一步,将乘法公式提取出来,单独形成一个作用于自身的方法,具体代码如下:

def get_step(self,direction,distance):
          return distance*direction
        
    def fill_moving(self):
        while len(self.x_values)<self.num_times:#循环不断运行,直到漫步包含所需数量的点num_times
            x_step = self.get_step(choice([1,-1]),choice([0,1,2,3,4,5]))     #直接调用get_step方法,使代码更加简洁
            y_step = self.get_step(choice([1,-1]),choice([0,1,2,3,4,5]))

通过完成第1问的优化,代码结构变得更加简洁明了。

动态实例生成与字典映射策略

接下来解决第2、3个问题:

1)为了实现生成实例个数n以及对应的移动次数num_times,可以考虑使用字典结构。其中,实例个数为key,对应的移动次数num_times为value。例如,当输入2时,字典结构可表示为caselist={'1':'150000', '2':'250000'}。

2)遍历字典中的每一项,将对应的key和value传递给由Rand_moving类创建的实例。key的数量决定了需要创建的实例个数,而对应的value值则作为移动次数。

3)输入的数字即为字典key的数量。在存入字典时,利用随机函数生成一个num_times的值,并将其保存到对应的value中。

整体实现思路如下:

New_case类实现与主程序交互

1,重新定义一个类New_case(),其作用是接收一个整数参数,并根据该参数自动生成一个字典。

class New_case():
    #定义New_case类
    def __init__(self,numbers): #定义要创建的实例个数        
        self.numbers=numbers     
        self.caselist={}  #定义一个空的caselist字典
        self.case = 0       
       while self.case < self.numbers: #当变量case小于给定值时,
            self.case += 1
            times = choice([100000,150000,200000,250000])#随机选择一个移动次数
            self.caselist[self.case] = times  #将value与key对应

2,需要循环读取字典中的key和value,将value传递给Rand_moving类,随后运行fill_moving()方法生成数据并保存到列表中,最后使用plt.scatter()进行绘图。

for key,value in self.caselist.items(): #字典不为空
            colorkey=str(key)        #  将字典关键字转为字符串存到变量colorkey中
            examplecase = Rand_moving(int(value))  #创建实例,将对应的value值传递类Rand_moving
            examplecase.fill_moving()  #调用类Rand_moving中的方法fill_moving()计算移动相关数据并保存到列表中
            plt.figure(dpi=128,figsize=(12, 10))   #创建画面屏幕          
            plt.scatter(examplecase.x_values,examplecase.y_values,c=self.colors[colorkey],s=15)
        plt.show()

上篇代码中使用了c=y_values, cmap=plt.cm.Reds,但在此处不再使用,因为在循环过程中一直出现红色Reds,为了进行对比,我们创建了一个新字典colors{},将生成的实例个数与颜色相对应。因此,上述代码中修改为c=self.colors[colorkey]。

类New_case()的完整代码如下:

import matplotlib.pyplot as plt

from rand_moving import *

class New_case():
    #定义New_case类
    def __init__(self,numbers): #定义要创建的实例个数        
        self.numbers=numbers     
        self.caselist={}  #定义一个空的cases列表
        self.case = 0    #定义一个case变量   
        self.colors={'1':'red','2':'orange','3':'yellow','4':'green','5':'blue','6':'puple'}#创建了一新字典colors{},将生成的个数与颜色相对应
        
        while self.case < self.numbers:  #小于给定实例个数时
            self.case += 1
            times = choice([100000,150000,200000,250000]) #随机生成一个移动次数
            self.caselist[self.case] = times    #将变量case作为key, times作为value保存到字典中      
       
    def case_moving(self):  #重新定义一个方法,即访问字典所有项
        for key,value in self.caselist.items(): #字典不为空
            colorkey=str(key)        #  将字典关键字转为字符串存到变量colorkey中
            examplecase = Rand_moving(int(value))  #创建实例,将对应的value值传递类Rand_moving
            examplecase.fill_moving()  #调用类Rand_moving中的方法fill_moving()计算移动相关数据并保存到列表中
            plt.figure(dpi=128,figsize=(12, 10))   #创建画面屏幕         
            plt.scatter(examplecase.x_values,examplecase.y_values,c=self.colors[colorkey],s=15)#注意调用了上述新字典的颜色
        plt.show()

3、主程序部分。

主程序中包含一个交互环节,需要用户输入一个数据,然后调用相关类来创建实例(感觉慢慢变成了“调包侠”!^v^)。

import matplotlib.pyplot as plt

from rand_moving import *   
from new_case import *

print("Please enter the number:")  #交互,请输入一个数,模拟运行,不需要太大的数据。
n = input()   #将输入的数据保存到变量n中,注意所有输入均为字符串,

testcase = New_case(int(n)) #将n转为整型数据,创建实例个数 
testcase.case_moving()

运行效果与可视化优化

实际运行效果如下,输入4,生成4个数据图形(为了展示更完整的内容,原图已缩小显示):

定义self.colors={'1':'red','2':'orange','3':'yellow','4':'green','5':'blue','6':'puple'},请注意图中颜色分别与colors字典中的定义相对应。

当然,如果觉得坐标轴碍眼,可以在New_case()类中的plt.figure()之后添加以下代码来隐藏坐标轴。

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

到此,关于Python利用随机函数生成变化图形的详解就介绍到这里了。更多相关Python随机函数生成变化图形内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表