为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中使用PDB库调试程序
Apr 05 Python
详谈Python高阶函数与函数装饰器(推荐)
Sep 30 Python
django 多数据库配置教程
May 30 Python
用pycharm开发django项目示例代码
Oct 24 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
Jan 30 Python
python3正则提取字符串里的中文实例
Jan 31 Python
Python发展简史 Python来历
May 14 Python
简单了解python 邮件模块的使用方法
Jul 24 Python
Python下利用BeautifulSoup解析HTML的实现
Jan 17 Python
Python猜数字算法题详解
Mar 01 Python
Python通过socketserver处理多个链接
Mar 18 Python
使用python+pygame开发消消乐游戏附完整源码
Jun 10 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
一个显示某段时间内每个月的方法 返回由这些月份组成的数组
2012/05/16 PHP
PHP闭包实例解析
2014/09/08 PHP
PHP+jQuery 注册模块开发详解
2014/10/14 PHP
DWZ+ThinkPHP开发时遇到的问题分析
2016/12/12 PHP
详谈配置phpstorm完美支持Codeigniter(CI)代码自动完成(代码提示)
2017/04/07 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
Javascript实现返回上一页面并刷新的小例子
2013/12/11 Javascript
js实现带按钮的上下滚动效果
2015/05/12 Javascript
JavaScript取得键盘按下方向键是哪个的方法
2015/08/04 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
JQuery学习总结【一】
2016/12/01 Javascript
JavaScript 网页中实现一个计算当年还剩多少时间的倒数计时程序
2017/01/25 Javascript
Vue.js中轻松解决v-for执行出错的三个方案
2017/06/09 Javascript
JS鼠标3次点击事件实现代码及扩展思路
2017/09/12 Javascript
详解使用React全家桶搭建一个后台管理系统
2017/11/04 Javascript
vue实现微信分享朋友圈,发送朋友的示例讲解
2018/02/10 Javascript
vue项目如何刷新当前页面的方法
2018/05/18 Javascript
vue生命周期实例小结
2018/08/15 Javascript
用js简单提供增删改查接口
2019/05/12 Javascript
以911新闻为例演示Python实现数据可视化的教程
2015/04/23 Python
Python 3.x 新特性及10大变化
2015/06/12 Python
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
python生成圆形图片的方法
2020/03/25 Python
详解Python_shutil模块
2019/03/15 Python
Python散点图与折线图绘制过程解析
2019/11/30 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
乌克兰最大的家用电器和电子产品连锁店:Eldorado
2019/10/02 全球购物
如何提高MySql的安全性
2014/06/19 面试题
浅谈react路由传参的几种方式
2021/03/23 Javascript
校园自助餐厅的创业计划书
2013/12/26 职场文书
迟到检讨书1000字
2014/01/15 职场文书
婚前协议书范本
2014/10/27 职场文书
加薪通知
2015/04/25 职场文书
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
2022/04/06 Vue.js