为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实现可将字符转换成大写的tcp服务器实例
Apr 29 Python
Python的多态性实例分析
Jul 07 Python
Python多层嵌套list的递归处理方法(推荐)
Jun 08 Python
TensorFlow 实战之实现卷积神经网络的实例讲解
Feb 26 Python
使用python3+xlrd解析Excel的实例
May 04 Python
Python绘制股票移动均线的实例
Aug 24 Python
python3.5 cv2 获取视频特定帧生成jpg图片
Aug 28 Python
如何分离django中的媒体、静态文件和网页
Nov 12 Python
pandas factorize实现将字符串特征转化为数字特征
Dec 19 Python
Python3 Tensorlfow:增加或者减小矩阵维度的实现
May 22 Python
Python使用内置函数setattr设置对象的属性值
Oct 16 Python
解决Pycharm 运行后没有输出的问题
Feb 05 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
多文件上载系统完整版
2006/10/09 PHP
php中使用Akismet防止垃圾评论的代码
2011/06/10 PHP
php 数据库字段复用的基本原理与示例
2011/07/22 PHP
在yii中新增一个用户验证的方法详解
2013/06/20 PHP
PHP中register_shutdown_function函数的基础介绍与用法详解
2017/11/28 PHP
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
2021/03/09 HTML / CSS
safari,opera嵌入iframe页面cookie读取问题解决方法
2010/06/23 Javascript
jQuery中RadioButtonList的功能及用法实例介绍
2013/08/23 Javascript
提升PHP安全:8个必须修改的PHP默认配置
2014/11/17 Javascript
Nodejs为什么选择javascript为载体语言
2015/01/13 NodeJs
jQuery基于cookie实现的购物车实例分析
2015/12/24 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
2016/08/24 Javascript
正则表达式替换html元素属性的方法
2016/11/26 Javascript
基于JavaScript+HTML5 实现打地鼠小游戏逻辑流程图文详解(附完整代码)
2017/11/02 Javascript
js设置随机切换背景图片的简单实例
2017/11/12 Javascript
如何在微信小程序中实现Mixins方案
2019/06/20 Javascript
django js 实现表格动态标序号的实例代码
2019/07/12 Javascript
基于vue3.0.1beta搭建仿京东的电商H5项目
2020/05/06 Javascript
将Python中的数据存储到系统本地的简单方法
2015/04/11 Python
在Python的Django框架中使用通用视图的方法
2015/07/21 Python
Python+django实现文件下载
2016/01/17 Python
转换科学计数法的数值字符串为decimal类型的方法
2018/07/16 Python
python try except 捕获所有异常的实例
2018/10/18 Python
Python判断对象是否相等及eq函数的讲解
2019/02/25 Python
Python常见数据类型转换操作示例
2019/05/08 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
2019/07/04 Python
python中hasattr()、getattr()、setattr()函数的使用
2019/08/16 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
jupyter notebook更换皮肤主题的实现
2021/01/07 Python
瑞典快乐袜子:Happy Socks
2018/02/16 全球购物
展览会邀请函
2015/02/02 职场文书
创业计划书之校园超市
2019/09/12 职场文书
图解上海144收音机
2021/04/22 无线电
用python批量解压带密码的压缩包
2021/05/31 Python
Python实现自动玩连连看的脚本分享
2022/04/04 Python