最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Python實(shí)現(xiàn)一個簡單的月相可視化器

 更新時間:2026年05月26日 09:22:55   作者:顏顏yan_  
這篇文章介紹了一個使用Python創(chuàng)建中秋節(jié)月相可視化系統(tǒng)的項(xiàng)目,項(xiàng)目通過精確的天文計(jì)算和優(yōu)雅的可視化技術(shù),實(shí)現(xiàn)了月相變化的動態(tài)展示,感興趣的小伙伴可以了解下

引言

中秋節(jié),這個承載著千年文化的傳統(tǒng)節(jié)日,以其獨(dú)特的滿月寓意著團(tuán)圓與和諧。我們不妨用Python這門優(yōu)雅的編程語言,來創(chuàng)造一個富有詩意的中秋節(jié)月相可視化器。本文將帶您通過代碼的藝術(shù),重現(xiàn)天空中月亮的盈虧變化,并在中秋節(jié)這個特殊的日子里,為我們的程序增添一抹傳統(tǒng)文化的色彩。

項(xiàng)目概述

我們將構(gòu)建一個功能豐富的月相可視化系統(tǒng),主要包含以下特性:

  • 精確的天文計(jì)算:基于29.53天月相周期的高精度算法
  • Web界面生成:自動生成華麗的HTML可視化界面
  • 視覺特效豐富:星空背景、流星效果、月亮光暈等
  • 多維度展示:時間軸、曲線圖、年度概覽等四種圖表
  • 中秋文化融入:詩詞展示、傳統(tǒng)裝飾元素

技術(shù)架構(gòu)解析

# 安裝依賴
pip install numpy matplotlib datetime base64 io warnings

項(xiàng)目結(jié)構(gòu)

moon-phase-visualizer/
├── moon_calculator.py      # 核心計(jì)算引擎
├── generate_html.py        # HTML生成器
└── moon_phase_2025_mid_autumn.html  # 生成的界面

實(shí)現(xiàn)思路

月相計(jì)算核心

月相變化周期是29.53天,選定2025年9月25日作為參考新月。通過計(jì)算目標(biāo)日期與參考點(diǎn)的時間差,結(jié)合朔望月周期進(jìn)行數(shù)學(xué)建模。

算法的關(guān)鍵是將連續(xù)時間變化映射到0-1的月相值:前半周期(新月→滿月),后半周期(滿月→新月)。

可視化難點(diǎn)

matplotlib中文顯示問題通過多字體回退解決:微軟雅黑 → 黑體 → 其他系統(tǒng)字體。月亮繪制用圓形+橢圓陰影實(shí)現(xiàn),陰影寬度根據(jù)月相值動態(tài)計(jì)算。中秋節(jié)特效包括多層光暈和星星裝飾。

核心模塊設(shè)計(jì)

moon_calculator.py- 核心計(jì)算引擎

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from datetime import datetime, timedelta
import math
import base64
import io
import warnings
from matplotlib import rcParams

warnings.filterwarnings('ignore')
# 設(shè)置matplotlib為非交互式后端
plt.switch_backend('Agg')

# 優(yōu)化中文字體設(shè)置
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False


class MoonPhaseCalculator:
    """月相計(jì)算器類"""

    def __init__(self):
        # 月相周期約為29.53天
        self.lunar_cycle = 29.530588853
        # 更新參考新月日期(2025年9月25日新月)
        self.reference_new_moon = datetime(2025, 9, 25)

    def get_moon_phase(self, date):
        """計(jì)算指定日期的月相"""
        days_since_new_moon = (date - self.reference_new_moon).total_seconds() / (24 * 3600)
        cycle_position = (days_since_new_moon % self.lunar_cycle) / self.lunar_cycle

        if cycle_position <= 0.5:
            phase = cycle_position * 2
        else:
            phase = 2 - (cycle_position * 2)

        return phase

    def get_moon_age(self, date):
        """計(jì)算月齡"""
        days_since_new_moon = (date - self.reference_new_moon).total_seconds() / (24 * 3600)
        return days_since_new_moon % self.lunar_cycle

    def is_mid_autumn_festival(self, date):
        """判斷是否為中秋節(jié)(2025年10月6日)"""
        mid_autumn_2025 = datetime(2025, 10, 6)
        return abs((date - mid_autumn_2025).days) == 0

    def get_mid_autumn_date(self, year=2025):
        """獲取指定年份的中秋節(jié)日期"""
        if year == 2025:
            return datetime(2025, 10, 6)
        elif year == 2024:
            return datetime(2024, 9, 17)
        elif year == 2026:
            return datetime(2026, 9, 25)
        else:
            return datetime(2025, 10, 6)

核心算法:

  • lunar_cycle = 29.530588853:朔望月精確天數(shù)
  • get_moon_phase() 通過時間差和模運(yùn)算計(jì)算月相值
  • 使用 total_seconds() 確保計(jì)算精度

可視化渲染類

class WebMoonVisualizer:
    """Web版月相可視化器"""

    def __init__(self):
        self.calculator = MoonPhaseCalculator()

    def draw_moon(self, ax, phase, size=1.0, position=(0, 0), is_mid_autumn=False):
        """繪制月亮形狀"""
        x, y = position

        # 繪制月亮基礎(chǔ)圓形
        circle = patches.Circle((x, y), size,
                                facecolor='lightyellow',
                                edgecolor='gold',
                                linewidth=2)
        ax.add_patch(circle)

        # 根據(jù)月相繪制陰影部分
        if phase < 0.95:
            shadow_width = size * 2 * (1 - phase)
            if shadow_width > 0.1:
                shadow = patches.Ellipse((x + size * 0.1, y), shadow_width, size * 2,
                                         facecolor='darkgray',
                                         alpha=0.6)
                ax.add_patch(shadow)

        # 中秋節(jié)特效
        if is_mid_autumn:
            for i in range(4):
                halo = patches.Circle((x, y), size * (1.3 + i * 0.15),
                                      facecolor='orange',
                                      alpha=0.12 - i * 0.03,
                                      edgecolor='none')
                ax.add_patch(halo)

            # 添加星星裝飾
            star_positions = [
                (x - size * 2.0, y + size * 1.0),
                (x + size * 2.0, y + size * 1.0),
                (x - size * 1.8, y - size * 1.3),
                (x + size * 1.8, y - size * 1.3),
            ]

            for sx, sy in star_positions:
                star = patches.RegularPolygon((sx, sy), 5,
                                              radius=size * 0.12,
                                              facecolor='gold',
                                              alpha=0.9)
                ax.add_patch(star)

    def get_phase_name(self, phase):
        """獲取月相名稱"""
        if phase < 0.1:
            return "新月"
        elif phase < 0.35:
            return "蛾眉月"
        elif phase < 0.65:
            return "上弦月"
        elif phase < 0.9:
            return "盈凸月"
        else:
            return "滿月"

繪制要點(diǎn):

  • patches.Circle 繪制月亮基礎(chǔ)形狀
  • 橢圓陰影模擬月相變化:shadow_width = size * 2 * (1 - phase)
  • 中秋特效:多層光暈 + 五角星裝飾
  • 顏色搭配:淡黃底色 + 金色邊框

四種圖表實(shí)現(xiàn)詳解

時間軸圖表 - 連續(xù)月相展示

def create_timeline_chart(self, center_date=None, days=30):
    """創(chuàng)建時間軸圖表(修復(fù)重疊問題)"""
    if center_date is None:
        center_date = datetime(2025, 10, 6)

    start_date = center_date - timedelta(days=15)
    fig, ax = plt.subplots(figsize=(24, 12))

    for i in range(days):
        current_date = start_date + timedelta(days=i)
        phase = self.calculator.get_moon_phase(current_date)
        is_mid_autumn = self.calculator.is_mid_autumn_festival(current_date)

        x_pos = i * 3.5  # 增大間距避免重疊
        y_pos = 0

        self.draw_moon(ax, phase, size=1.0,
                       position=(x_pos, y_pos),
                       is_mid_autumn=is_mid_autumn)

        # 添加日期標(biāo)簽
        ax.text(x_pos, -3.0, current_date.strftime('%m-%d'),
                ha='center', va='top', fontsize=11, fontweight='bold')

        # 中秋節(jié)特殊標(biāo)記
        if is_mid_autumn:
            ax.text(x_pos, 3.5, '2025年中秋節(jié)',
                    ha='center', va='bottom',
                    fontsize=14, fontweight='bold',
                    color='red')

實(shí)現(xiàn)關(guān)鍵:

  • x_pos = i * 3.5:間距設(shè)置避免重疊
  • 24x12大畫布確保顯示完整
  • 中秋節(jié)用紅色高亮 + 邊框裝飾

月相曲線圖 - 數(shù)學(xué)規(guī)律可視化

def create_phase_chart(self):
    """創(chuàng)建月相圖表"""
    fig, ax = plt.subplots(figsize=(12, 8))
    ax.set_facecolor('#001133')

    today = datetime(2025, 10, 6)
    dates_range = [today + timedelta(days=i - 15) for i in range(31)]
    phase_values = [self.calculator.get_moon_phase(d) for d in dates_range]

    ax.plot(range(31), phase_values, 'gold', linewidth=4, marker='o',
            markersize=6, markerfacecolor='yellow', markeredgecolor='orange')
    ax.fill_between(range(31), phase_values, alpha=0.3, color='gold')
    
    # 重要標(biāo)記線
    ax.axhline(y=1.0, color='red', linestyle='--', alpha=0.8, linewidth=2, label='Full Moon')
    ax.axhline(y=0.0, color='silver', linestyle='--', alpha=0.8, linewidth=2, label='New Moon')
    ax.axvline(x=15, color='lime', linestyle=':', alpha=0.8, linewidth=3, label='Mid-Autumn Festival')

    mid_autumn_phase = self.calculator.get_moon_phase(today)
    ax.plot(15, mid_autumn_phase, 'r*', markersize=15, label=f'Festival Phase({mid_autumn_phase:.2f})')

設(shè)計(jì)要點(diǎn):

  • 深藍(lán)背景+ 金色曲線營造夜空效果
  • fill_between 創(chuàng)建填充區(qū)域增強(qiáng)視覺效果
  • 水平/垂直參考線標(biāo)注關(guān)鍵點(diǎn)
  • 紅色星標(biāo)突出中秋節(jié)位置

當(dāng)前月相圖

def create_current_moon(self):
    """創(chuàng)建當(dāng)前月相圖"""
    fig, ax = plt.subplots(figsize=(8, 8))
    ax.set_facecolor('#001133')

    today = datetime(2025, 10, 6)
    phase_today = self.calculator.get_moon_phase(today)
    is_today_mid_autumn = self.calculator.is_mid_autumn_festival(today)

    self.draw_moon(ax, phase_today, size=3.0, position=(0, 0),
                   is_mid_autumn=is_today_mid_autumn)

    ax.set_xlim(-6, 6)
    ax.set_ylim(-6, 6)
    ax.set_aspect('equal')
    ax.axis('off')

    phase_name = self.get_phase_name(phase_today)
    title = f'2025 Mid-Autumn Festival Moon Phase - {phase_name}\n{today.strftime("%Y-%m-%d")}\nPhase Value: {phase_today:.3f}'

    if is_today_mid_autumn:
        title += '\nHappy Mid-Autumn Festival!'

    ax.text(0, -5, title, ha='center', va='top', fontsize=14,
            color='white', fontweight='bold',
            bbox=dict(boxstyle="round,pad=0.8", facecolor="darkblue", alpha=0.8))

技術(shù)特點(diǎn):

  • 8x8正方形畫布保證月亮圓形顯示
  • size=3.0 大尺寸突出視覺效果
  • 圓角文本框顯示詳細(xì)信息

圖像Base64編碼

def fig_to_base64(self, fig):
    """將matplotlib圖形轉(zhuǎn)換為base64字符串"""
    buffer = io.BytesIO()
    fig.savefig(buffer, format='png', facecolor=fig.get_facecolor(),
                bbox_inches='tight', dpi=150)
    buffer.seek(0)
    image_png = buffer.getvalue()
    buffer.close()
    plt.close(fig)

    graphic = base64.b64encode(image_png)
    return graphic.decode('utf-8')

要點(diǎn):

  • 內(nèi)存緩沖區(qū)避免臨時文件
  • dpi=150 平衡質(zhì)量與大小
  • plt.close(fig) 釋放內(nèi)存防止泄漏

HTML界面生成

generate_html.py- 界面組裝器

from moon_calculator import WebMoonVisualizer
from datetime import datetime


def generate_html():
    visualizer = WebMoonVisualizer()

    # 生成圖表
    mid_autumn_date = datetime(2025, 10, 6)
    timeline_fig = visualizer.create_timeline_chart(mid_autumn_date, days=30)
    timeline_img = visualizer.fig_to_base64(timeline_fig)

    phase_fig = visualizer.create_phase_chart()
    phase_img = visualizer.fig_to_base64(phase_fig)

    current_fig = visualizer.create_current_moon()
    current_img = visualizer.fig_to_base64(current_fig)

    annual_fig = visualizer.create_annual_overview()
    annual_img = visualizer.fig_to_base64(annual_fig)

    # 獲取月相信息
    moon_info = visualizer.get_moon_info()

CSS3特效設(shè)計(jì)

/* 星空背景動畫 */
@keyframes twinkle {
    0%, 100% { opacity: 0.3; }
    50% { opacity: 1; }
}
/* 流星效果 */
@keyframes shooting {
    0% { transform: rotate(-45deg) translateX(0) translateY(0); opacity: 1; }
    100% { transform: rotate(-45deg) translateX(-800px) translateY(800px); opacity: 0; }
}
/* 月亮背景浮動 */
@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50% { transform: translateY(-15px); }
}
/* 漸變文字效果 */
.highlight {
    background: linear-gradient(45deg, #ff6b35, #f7931e, #ffd700);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: gradient-shift 3s ease infinite;
}

JavaScript交互特效

// 創(chuàng)建120顆星星
function createStars() {
    const starsContainer = document.getElementById('stars');
    const numberOfStars = 120;
    for (let i = 0; i < numberOfStars; i++) {
        const star = document.createElement('div');
        star.className = 'star';
        star.style.left = Math.random() * 100 + '%';
        star.style.top = Math.random() * 100 + '%';
        const size = Math.random() * 3 + 1;
        star.style.width = size + 'px';
        star.style.height = size + 'px';
        star.style.animationDelay = Math.random() * 3 + 's';
        starsContainer.appendChild(star);
    }
}
// 流星效果
function createShootingStar() {
    const shootingStar = document.createElement('div');
    shootingStar.className = 'shooting-star';
    const startX = Math.random() * window.innerWidth;
    const startY = Math.random() * (window.innerHeight * 0.5);
    shootingStar.style.left = startX + 'px';
    shootingStar.style.top = startY + 'px';
    shootingStar.style.animation = 'shooting 1.5s linear forwards';
    document.body.appendChild(shootingStar);
    setTimeout(() => {
        shootingStar.remove();
    }, 1500);
}

特效實(shí)現(xiàn):

  • 120顆隨機(jī)分布的閃爍星星
  • 流星從隨機(jī)位置斜向劃過
  • 自動清理DOM防止內(nèi)存泄漏

結(jié)語

正如古人所言:"但愿人長久,千里共嬋娟。"愿我們的代碼也能像這輪明月一樣,在技術(shù)的夜空中永遠(yuǎn)閃耀著智慧的光芒,連接著傳統(tǒng)與未來,架起文化與科技的橋梁。

以上就是基于Python實(shí)現(xiàn)一個簡單的月相可視化器的詳細(xì)內(nèi)容,更多關(guān)于Python月相可視化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

霞浦县| 阿拉善右旗| 友谊县| 华阴市| 郎溪县| 大安市| 宿迁市| 石景山区| 瓮安县| 灵山县| 裕民县| 尖扎县| 大同县| 富平县| 丰顺县| 冕宁县| 平和县| 沁源县| 府谷县| 顺义区| 田阳县| 平南县| 乌审旗| 舟曲县| 左贡县| 陆河县| 河东区| 孟州市| 临安市| 阜城县| 松潘县| 浙江省| 达州市| 浮梁县| 汪清县| 湘阴县| 手游| 汉阴县| 涡阳县| 盐津县| 香港|