为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通过函数属性实现全局变量的方法
May 16 Python
Python的Twisted框架中使用Deferred对象来管理回调函数
May 25 Python
Django查询数据库的性能优化示例代码
Sep 24 Python
python组合无重复三位数的实例
Nov 13 Python
python3爬虫怎样构建请求header
Dec 23 Python
python实现微信每日一句自动发送给喜欢的人
Apr 29 Python
对Python 检查文件名是否规范的实例详解
Jun 10 Python
解决Python3下map函数的显示问题
Dec 04 Python
Python如何读写CSV文件
Aug 13 Python
python实现马丁策略回测3000只股票的实例代码
Jan 22 Python
python绘制高斯曲线
Feb 19 Python
Pyhton爬虫知识之正则表达式详解
Apr 01 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
ThinkPHP实现将SESSION存入MYSQL的方法
2014/07/22 PHP
完美解决thinkphp验证码出错无法显示的方法
2014/12/09 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
php5.x禁用eval的操作方法
2018/10/19 PHP
一次因composer错误使用引发的问题与解决
2019/03/06 PHP
PHP SESSION机制的理解与实例
2019/03/22 PHP
初窥JQuery(二) 事件机制(1)
2010/11/25 Javascript
js 调用父窗口的具体实现代码
2013/07/15 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
基于javascript html5实现多文件上传
2016/03/03 Javascript
JavaScript中省略元素对数组长度的影响
2016/10/26 Javascript
JavaScript实现两个select下拉框选项左移右移
2017/03/09 Javascript
在小程序中集成redux/immutable/thunk第三方库的方法
2018/08/12 Javascript
30分钟精通React今年最劲爆的新特性——React Hooks
2019/03/11 Javascript
Vue编写可显示周和月模式的日历 Vue自定义日历内容的显示
2019/06/26 Javascript
es6中reduce的基本使用方法
2019/09/10 Javascript
《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
2020/04/08 Javascript
微信小程序文章列表功能完整实例
2020/06/03 Javascript
vue 实现tab切换保持数据状态
2020/07/21 Javascript
PYTHON压平嵌套列表的简单实现
2016/06/08 Python
python实现文本界面网络聊天室
2018/12/12 Python
Python异常处理知识点总结
2019/02/18 Python
基于python实现蓝牙通信代码实例
2019/11/19 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
使用Keras中的ImageDataGenerator进行批次读图方式
2020/06/17 Python
python3中布局背景颜色代码分析
2020/12/01 Python
CSS3实现鼠标悬停显示扩展内容
2016/08/24 HTML / CSS
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
挑战杯创业计划书的写作指南
2014/01/07 职场文书
学校安全管理责任书
2014/07/23 职场文书
2014年财务工作自我评价
2014/09/23 职场文书
领导班子四风问题对照检查材料
2014/09/27 职场文书
会计求职自荐信范文
2015/03/04 职场文书
人工作失职检讨书
2015/05/05 职场文书
2015年大学生暑期实习报告
2015/07/13 职场文书
vue实现无缝轮播效果(跑马灯)
2021/05/14 Vue.js