python 实现 画图器_做一个本地网络画图器,并在python中指挥它完成“正态分布模拟机”【开源】...

在纯python环境中使用processing的实时画图功能

processing的实时画图功能是很强大的,他提供了最便捷简洁的画图函数,是强大的可视化工具。但是这样的工具也是存在问题的,那就是无法在一般的python环境中使用processing。经过了各种探索,我终于找到了在本地最便捷的从一般python环境中调用processing进行动态可视化的方法,那就在一般的python程序中通过本地网络连接到processing:

具体的说,就是先启动一个processing程序,然后再启动python程序,让两者通过本地网络连接进行通讯,从而使得python程序能够给processing程序发指令。

程序的复杂的代码逻辑都在python中,而不是在processing中,从而使得我们的方案能够被广大的python使用者所使用。processing中的程序体量小,而且是设计好的通用性程序,使得使用者基本不必对其进行更改,从而变得更加方便。最终将processing丰富高效的可视化能力与python的丰富的科学计算生态以及强大的IDE环境的长处共同发挥出来。

在本文中,我们以一个有趣的例子为例,介绍了我们的processing画图器,以及如何在python程序中使用它。而且,整个项目已经有了对应的Git仓库。

本文的内容包括:画图器使用例子:正态分布抽奖机展示

如何启动processing画图器

Python中如何调用画图器-----发指令前的准备工作:先将python连接到画图器程序

-----rpc指令格式

-----rpc指令的批量发送在普通python环境中使用画图器实现“抽奖机”

画图器方案内部细节展示

画图器使用例子:正态分布抽奖机展示

看一下程序效果:v2-c148b5db3219f3cdce624b340b31888f.jpg可视化方案的效果验证https://www.zhihu.com/video/1167184987182358528

可以看出,在每一帧的指令数达到几十条几百条的时候,可视化图像依旧非常流畅,验证了我们方案的可行性。该程序的具体功能是这样的:从三角堆的顶部持续产生下降的小球。

小球在三角堆中从上一行的某个位置(该行白点中的某个白点的位置)走到下一行的两个相邻位置中的一个,且走到下行两个位置各自的概况相同。

小球离开三角堆后迅速降落到底部。

画面底部还有一个柱形图统计落到每个位置的小球的累计数量。由概率论的知识可以知道,底部的统计条形图基本是依照正态分布而分布的。

(之所以在小标题上加了一个问号❓,是因为不知道这个装置的学名(正式的,惯用的名字)是什么。)

如何启动processing画图器

方法1:

下载python,安装python模式,然后将画图器代码复制到新建立的processingpy工程中,然后点击processing编辑器的启动按钮,从而运行。

方法2:

在下面的路径中,有作者已经上传的打包好的win 程序。在windows系统中下载整个文件夹,然后双击exe文件即可启动画图器。https://github.com/shiyunlai233/Processing_Ploter_for_python/tree/master/ploter​github.com

Python中如何调用画图器

发指令前的准备工作:先将python连接到画图器程序

python程序和画图器之间的连接方式是:在本地网络连接的基础上,进行远程过程调用(RPC)。所以我们先使用python中内置的socket库,连接到画图器的地址:127.0.0.1:12345。然后将下面的RPC类进行实例化,得到rpc,就可以通过对rpc进行操作,实现对于画图器的控制了。具体到我们的程序中,就是说在python程序中要想控制画图器,就需要先启动画图器,并在python中运行以下代码片段:

import socket, json, pickle

class RPCProxy:

def __init__(self, connection):

self._connection = connection

self.data = []

def __getattr__(self, name):

def do_rpc(*args, **kwargs):

self.data.append(json.dumps((name, args, kwargs)))

return do_rpc

def send_all(self):

self._connection.send(pickle.dumps(self.data, protocol=0))

self.data.clear()

address = ('127.0.0.1', 12345)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect(address) # 连接到画图器

rpc = RPCProxy(s) # 得到了rpc

rpc指令格式

画图端程序的画图指令函数用法,和processing中的编程命令是非常类似的,只是在每个函数的前面加了一个 “rpc.” 比如原先在processing中的圆指令就从circle()变成了rpc.circle()。比如说上面的画图程序就来自processing官网的一个入门教程。对应的在processing中的画图命令是这样的:

# python中给画图器发出的命令

rpc.rect(100,100,20,100)

rpc.ellipse(100,70,60,60)

rpc.ellipse(81,70,16,32)

rpc.ellipse(119,70,16,32)

rpc.line(90,150,80,160)

rpc.line(110,150,120,160)

# 效果相同的processing程序代码

rect(100,100,20,100);

ellipse(100,70,60,60);

ellipse(81,70,16,32);

ellipse(119,70,16,32);

line(90,150,80,160);

line(110,150,120,160);

可用的画图命令包括:arc, circle, ellipse, line, point, quad, rect, square, triangle, fill, stroke, background, 这些命令的详细用法和在processing中是一致的,可以参考:processing reference。在本文程序中,只用到了画圆指令circle和画方指令rect。

rpc指令的批量发送

为了高效而准确地利用画图器指令,我们还需要一个额外的rpc指令rpc.send_all()。在执行这条命令后,会将之前的rpc指令统一发送给画图器,并清空python中的rpc指令缓存。

建议最好每发送完对于一帧的画图指令后,再进行rpc.send_all()。因为这样就能实现画面流畅度的最大化。

所以现在python程序中发出可视化指令的框架是这样的:

for i in rane(100):

rpc.background(0) # 画背景(在最后一行代码处发送)

rpc.circle() # 画原指令(在最后一行代码处发送)

rpc.rect() # 其他画图指令(在最后一行代码处发送)

rpc.send_all() # 发出这一帧对应的所有指令

使用画图器实现“抽奖机”的python代码

在启动画图器后,在python环境中运行画图器代码,就能够获得我们上面视频中的效果了。

想要观看“抽奖机”完整代码可以前往对应Git仓库:https://github.com/shiyunlai233/Processing_Ploter_for_python/blob/master/examples/Normally_distributed_lottery_machine.py​github.com

做了一个画图器的完整使用视频:v2-6bbef1ae0ada2efc8b3a650cbb3aa170.jpghttps://www.zhihu.com/video/1184931701171638272

画图器方案内部细节展示

1 编码方式的改进:

这次的编码使用了: 指令 → json编码 →多条指令组成list → 对list进行pickle编码 → 发送。而在processing中的解码就是与之相反的流程。

这样的编码方式和上次的实现相比有哪些优点:1,指令之间不再需要插入间隔符。2,指令在传输过程中使用的是pickle编码的结果,而不是json编码的结果,效率更高。

2 传输方式的改进:

上次的方法是逐条命令传递,逐条命令执行。这样产生的问题是,由于在python程序中对同一帧画面发出指令的间隔可能会比较大,导致可视化画面闪烁,或者有其他不好的现象。

所以改进成了先将同一帧的指令组装成一个list,然后对这一帧的所有指令统一发送,统一执行的方法,从而实现了画图器方案的优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值