为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景


Posted in Python onJanuary 05, 2021

一场大雪,覆盖了华北、华东。天地连成一片,城市银装素裹,处处诗情画意、人人兴高采烈。朋友圈被雪景图和调侃路滑摔跤的段子刷屏,气氛比过年还要热烈几分。我也来凑个热闹,用python为2020年的第一场雪锦上添花。

绘制雪花图案,网上有很多文章介绍,但几乎都是用 Python 的内置模块 turtle 绘制的,这个模块适合用来引导孩子学习编程,很难真正用在项目开发上。也有用 pygame 实现的,不过 pygame 追求的是动画效果,雪花图案是随机生成的圆,效果很一般。

用 matplotlib 绘制雪花,重点是生成科赫曲线(Koch Curve)。科赫曲线是一种分形,其形态似雪花,又称科赫雪花、雪花曲线。给定线段pq,k阶科赫曲线可以由以下步骤生成:

  • 找出三等分点u、v
  • 以线段uv为底,向外(或内外)画等边三角形uwv
  • 将线段uv移除
  • 对pq之间的每一段重复上述操作k-1次

科赫雪花是以等边三角形三边生成的科赫曲线组成的。基于上述分析,我们可以很容易地写出科赫雪花的生成函数:给定一个等边三角形,和科赫曲线阶数k,返回科赫雪花图案中的所有点。

import numpy as np

plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False #解决中文显示为方块的问题

def rotate(p, d):
  """返回点p绕原点逆时针旋转d度的坐标"""
  
  a = np.radians(d)
  m = np.array([[np.cos(a), np.sin(a)],[-np.sin(a), np.cos(a)]])
  return np.dot(p, m)

def koch_curve(p, q):
  """将线段pq生成科赫曲线,返回uvw三个点"""
  
  p, q = np.array(p), np.array(q)
  u = p + (q-p)/3 # 三等分点u的坐标
  v = q - (q-p)/3 # 三等分点V的坐标
  w = rotate(v-u, 60) + u # 线段uv绕u点逆时针旋转60°得到点w的坐标
  
  return u.tolist(), v.tolist(), w.tolist()
  
def snow(triangle, k):
  """给定三角形,生成封闭的科赫雪花"""
  
  for i in range(k):
    result = list()
    t_len = len(triangle)
    for j in range(t_len):
      p = triangle[j]
      q = triangle[(j+1)%t_len]
      u, v, w = koch_curve(p, q)
      result.extend([p, u, w, v])
    triangle = result.copy()
  
  triangle.append(triangle[0])
  return triangle

有了雪花图案的数据,接下来使用 matplotlib 绘图就非常轻松了:

import numpy as np
import matplotlib.pyplot as plt

def plot_snow(snow_list):
  """绘制雪花"""
  
  for triangle, k in snow_list:
    data = np.array(snow(triangle, k))
    x, y = np.split(data, 2, axis=1)
    plt.plot(x, y)
  
  plt.axis('equal') 
  plt.show()

snow_list = [
  ([(0,0), (0.5,0.8660254), (1,0)], 5),
  ([(1.1,0.4), (1.35,0.8330127), (1.6,0.4)], 4),
  ([(1.1,-0.1), (1.25,0.15980761), (1.4,-0.1)], 3)
]
plot_snow(snow_list)

来看看我们的雪花效果。从小到大,3片雪花分别对应的是3阶、4阶、5阶的科赫雪花。

为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景

更进一步,我们还可以把雪花画在背景图上,配合大小浓淡的变化,画出另一种韵味的雪景图。

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def draw_scenery():
  """绘制雪景图"""
  
  im = Image.open('brage.png')
  bg = np.array(im)
  plt.imshow(bg) # 绘制背景图
  
  for i in range(80):
    x = np.random.randint(80, im.size[0]-80)
    y = np.random.randint(30, im.size[1]-30)
    r = np.random.randint(5, 20)
    a = np.random.random()*0.6 + 0.2
    v = np.array((x-r/2, y))
    u = np.array((x+r/2, y))
    w = rotate(v-u, 60) + u
    
    data = np.array(snow([(u[0],u[1]),(w[0],w[1]),(v[0],v[1])], 5))
    x, y = np.split(data, 2, axis=1)
    plt.plot(x, y, c='#AABBCC', lw=1, ls='-', alpha=a)
  
  plt.axis('equal') 
  plt.show()

draw_scenery()

为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景

到此这篇关于为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景的文章就介绍到这了,更多相关matplotlib绘制雪花和雪景内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python 实现文件的递归拷贝实现代码
Aug 02 Python
PyCharm 常用快捷键和设置方法
Dec 20 Python
Python图像处理之识别图像中的文字(实例讲解)
May 10 Python
Python设计模式之观察者模式原理与用法详解
Jan 16 Python
python实现K近邻回归,采用等权重和不等权重的方法
Jan 23 Python
python 实现读取一个excel多个sheet表并合并的方法
Feb 12 Python
python打包exe开机自动启动的实例(windows)
Jun 28 Python
画pytorch模型图,以及参数计算的方法
Aug 17 Python
详解pycharm连接不上mysql数据库的解决办法
Jan 10 Python
Python类中self参数用法详解
Feb 13 Python
matplotlib 画双轴子图无法显示x轴的解决方法
Jul 27 Python
Pycharm自动添加文件头注释和函数注释参数的方法
Oct 23 Python
Matplotlib中rcParams使用方法
Jan 05 #Python
matplotlib常见函数之plt.rcParams、matshow的使用(坐标轴设置)
Jan 05 #Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
Jan 05 #Python
matplotlib制作雷达图报错ValueError的实现
Jan 05 #Python
python实现三种随机请求头方式
Jan 05 #Python
scrapy实践之翻页爬取的实现
Jan 05 #Python
python里glob模块知识点总结
Jan 05 #Python
You might like
PHP下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
PHP中PDO基础教程 入门级
2011/09/04 PHP
PHP面向对象法则
2012/02/23 PHP
PHP获取时间排除周六、周日的两个方法
2014/06/30 PHP
PHP命令行脚本接收传入参数的三种方式
2014/08/20 PHP
php多次include后导致全局变量global失效的解决方法
2015/02/28 PHP
php mysql procedure实现获取多个结果集的方法【基于thinkPHP】
2016/11/09 PHP
Javascript实例教程(19) 使用HoTMetal(6)
2006/12/23 Javascript
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
javascript中取前n天日期的两种方法分享
2014/01/26 Javascript
js获取网页可见区域、正文以及屏幕分辨率的高度
2014/05/15 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
使用AngularJS中的SCE来防止XSS攻击的方法
2015/06/18 Javascript
JavaScript制作淘宝星级评分效果的思路
2020/06/23 Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
vue组件之间的数据传递方法详解
2019/04/19 Javascript
fastadmin中调用js的方法
2019/05/14 Javascript
python统计文本文件内单词数量的方法
2015/05/30 Python
Python中map,reduce,filter和sorted函数的使用方法
2015/08/17 Python
老生常谈Python之装饰器、迭代器和生成器
2017/07/26 Python
用matplotlib画等高线图详解
2017/12/14 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
对Python 文件夹遍历和文件查找的实例讲解
2018/04/26 Python
windows下python安装pip图文教程
2018/05/25 Python
Python 实现PS滤镜的旋涡特效
2020/12/03 Python
HTML5 本地存储和内容按需加载的思路和方法
2011/04/07 HTML / CSS
htnl5利用svg页面高斯模糊的方法
2018/07/20 HTML / CSS
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
通信工程专业女生个人求职信
2013/09/21 职场文书
平面设计自荐信
2013/10/07 职场文书
食堂采购员岗位职责
2014/03/17 职场文书
党性观念心得体会
2014/09/03 职场文书
2014年办公室文员工作总结
2014/11/12 职场文书
大学生个人学年总结
2015/02/15 职场文书
python超详细实现完整学生成绩管理系统
2022/03/17 Python