{
  "schemaVersion": "1.0",
  "item": {
    "slug": "plot",
    "name": "Pywayne Plot",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/wangyendt/plot",
    "canonicalUrl": "https://clawhub.ai/wangyendt/plot",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/plot",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=plot",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/plot"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/plot",
    "agentPageUrl": "https://openagent3.xyz/skills/plot/agent",
    "manifestUrl": "https://openagent3.xyz/skills/plot/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/plot/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Pywayne Plot",
        "body": "Enhanced spectrogram visualization tools for professional time-frequency analysis."
      },
      {
        "title": "Quick Start",
        "body": "import matplotlib.pyplot as plt\nfrom pywayne.plot import regist_projection, parula_map\nimport numpy as np\n\n# Register custom projection\nregist_projection()\n\n# Create spectrogram\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=signal_data,\n    Fs=100,\n    NFFT=128,\n    noverlap=96,\n    cmap=parula_map,\n    scale='dB'\n)\nax.set_ylabel('Frequency (Hz)')\nplt.colorbar(im, label='Magnitude (dB)')\nplt.show()"
      },
      {
        "title": "regist_projection",
        "body": "Register the custom SpecgramAxes projection. Must be called before using the enhanced specgram functionality.\n\nfrom pywayne.plot import regist_projection\nregist_projection()"
      },
      {
        "title": "SpecgramAxes.specgram",
        "body": "Enhanced spectrogram with advanced features.\n\nKey Parameters:\n\nParameterDescriptionDefaultNFFTFFT window length (points)256FsSampling frequency (Hz)2noverlapOverlap points between windows128cmapColormap (use parula_map)-mode'psd', 'magnitude', 'angle', 'phase''psd'scale'dB' or 'linear''dB'normalize'global', 'local', 'none''global'freq_scaleFrequency scaling factor1.0FcCenter frequency offset (Hz)0\n\nReturns:\n\nspec - 2D spectrogram array (n_freqs, n_times)\nfreqs - Frequency axis array\nt - Time axis array\nim - matplotlib image object (for colorbar)"
      },
      {
        "title": "get_specgram_params",
        "body": "Auto-recommend STFT parameters based on signal characteristics.\n\nfrom pywayne.plot import get_specgram_params\n\nparams = get_specgram_params(\n    signal_length=10000,\n    sampling_rate=100,\n    time_resolution=0.1  # or freq_resolution=0.5\n)\n# Returns: NFFT, noverlap, actual_freq_res, actual_time_res, n_segments"
      },
      {
        "title": "parula_map",
        "body": "MATLAB-style perceptually uniform colormap for scientific visualization.\n\nfrom pywayne.plot import parula_map\nplt.imshow(data, cmap=parula_map)"
      },
      {
        "title": "IMU Signal Analysis",
        "body": "fs = 100  # Sampling rate\nwin_time, step_time = 1, 0.1\n\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=acc_data,\n    Fs=fs,\n    NFFT=int(win_time * fs),\n    noverlap=int((win_time - step_time) * fs),\n    scale='dB',\n    cmap=parula_map\n)\nax.set_ylabel('Frequency (Hz)')\nax.set_ylim(0, 30)"
      },
      {
        "title": "Physiological Signals (PPG - Heart Rate)",
        "body": "# Convert Hz to bpm for heart rate visualization\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=ppg_signal,\n    Fs=100,\n    NFFT=400,\n    noverlap=300,\n    freq_scale=60,  # Hz -> bpm\n    scale='dB'\n)\nax.set_ylabel('Heart Rate (bpm)')\nax.set_ylim(40, 180)"
      },
      {
        "title": "Vibration Analysis with Global Normalization",
        "body": "fig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=vibration_data,\n    Fs=1000,\n    NFFT=1024,\n    noverlap=512,\n    scale='linear',\n    normalize='global'\n)\nplt.colorbar(im, label='Normalized Magnitude')"
      },
      {
        "title": "High-Resolution Analysis with Zero-Padding",
        "body": "fig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=signal,\n    Fs=100,\n    NFFT=100,\n    pad_to=512,  # Zero-pad for smoother spectrum\n    noverlap=80,\n    scale='dB'\n)"
      },
      {
        "title": "Scale Modes",
        "body": "ModeDescriptionUse CasedBLogarithmic (10log10 for PSD, 20log10 for magnitude)Large dynamic range signalslinearLinear amplitudeDirect amplitude comparison"
      },
      {
        "title": "Normalization Modes (only for scale='linear')",
        "body": "ModeDescriptionUse CaseglobalZ/max(Z), preserves relative intensityCompare intensity across timelocalPer-column normalization to [0,1]Focus on frequency content over timenoneNo normalizationRaw spectrogram values"
      },
      {
        "title": "Frequency Scaling",
        "body": "freq_scaleUnitUse Case1.0HzDefault, most signals60bpmHeart rate, respiration rate0.001kHzAudio signals\n\nExample: freq_scale=60 converts 2 Hz → 120 bpm"
      },
      {
        "title": "Resolution Guidelines",
        "body": "Frequency resolution: Δf = Fs / NFFT\nTime resolution: Δt = (NFFT - noverlap) / Fs\nTrade-off: Cannot simultaneously achieve high frequency and time resolution\n\nUse get_specgram_params() to auto-calculate optimal parameters."
      },
      {
        "title": "Interactive Analysis",
        "body": "spec, freqs, t, im = ax.specgram(...)\n\ndef on_click(event):\n    if event.xdata and event.inaxes == ax:\n        time_idx = np.argmin(np.abs(t - event.xdata))\n        plt.figure()\n        plt.plot(freqs, spec[:, time_idx])\n        plt.title(f'FFT at t={event.xdata:.2f}s')\n        plt.show()\n\nfig.canvas.mpl_connect('button_press_event', on_click)"
      },
      {
        "title": "Application Areas",
        "body": "IMU data: Accelerometer and gyroscope analysis\nPhysiological signals: PPG (heart rate), ECG, respiration\nVibration analysis: Machinery fault diagnosis\nAudio processing: Speech and audio spectrum analysis"
      },
      {
        "title": "Notes",
        "body": "Always call regist_projection() before using projection='z_norm'\nparula_map is recommended for best perceptual uniformity\ndB mode automatically handles log(0) issues\nFor better FFT efficiency, set NFFT to power of 2"
      }
    ],
    "body": "Pywayne Plot\n\nEnhanced spectrogram visualization tools for professional time-frequency analysis.\n\nQuick Start\nimport matplotlib.pyplot as plt\nfrom pywayne.plot import regist_projection, parula_map\nimport numpy as np\n\n# Register custom projection\nregist_projection()\n\n# Create spectrogram\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=signal_data,\n    Fs=100,\n    NFFT=128,\n    noverlap=96,\n    cmap=parula_map,\n    scale='dB'\n)\nax.set_ylabel('Frequency (Hz)')\nplt.colorbar(im, label='Magnitude (dB)')\nplt.show()\n\nFunctions\nregist_projection\n\nRegister the custom SpecgramAxes projection. Must be called before using the enhanced specgram functionality.\n\nfrom pywayne.plot import regist_projection\nregist_projection()\n\nSpecgramAxes.specgram\n\nEnhanced spectrogram with advanced features.\n\nKey Parameters:\n\nParameter\tDescription\tDefault\nNFFT\tFFT window length (points)\t256\nFs\tSampling frequency (Hz)\t2\nnoverlap\tOverlap points between windows\t128\ncmap\tColormap (use parula_map)\t-\nmode\t'psd', 'magnitude', 'angle', 'phase'\t'psd'\nscale\t'dB' or 'linear'\t'dB'\nnormalize\t'global', 'local', 'none'\t'global'\nfreq_scale\tFrequency scaling factor\t1.0\nFc\tCenter frequency offset (Hz)\t0\n\nReturns:\n\nspec - 2D spectrogram array (n_freqs, n_times)\nfreqs - Frequency axis array\nt - Time axis array\nim - matplotlib image object (for colorbar)\nget_specgram_params\n\nAuto-recommend STFT parameters based on signal characteristics.\n\nfrom pywayne.plot import get_specgram_params\n\nparams = get_specgram_params(\n    signal_length=10000,\n    sampling_rate=100,\n    time_resolution=0.1  # or freq_resolution=0.5\n)\n# Returns: NFFT, noverlap, actual_freq_res, actual_time_res, n_segments\n\nparula_map\n\nMATLAB-style perceptually uniform colormap for scientific visualization.\n\nfrom pywayne.plot import parula_map\nplt.imshow(data, cmap=parula_map)\n\nUsage Examples\nIMU Signal Analysis\nfs = 100  # Sampling rate\nwin_time, step_time = 1, 0.1\n\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=acc_data,\n    Fs=fs,\n    NFFT=int(win_time * fs),\n    noverlap=int((win_time - step_time) * fs),\n    scale='dB',\n    cmap=parula_map\n)\nax.set_ylabel('Frequency (Hz)')\nax.set_ylim(0, 30)\n\nPhysiological Signals (PPG - Heart Rate)\n# Convert Hz to bpm for heart rate visualization\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=ppg_signal,\n    Fs=100,\n    NFFT=400,\n    noverlap=300,\n    freq_scale=60,  # Hz -> bpm\n    scale='dB'\n)\nax.set_ylabel('Heart Rate (bpm)')\nax.set_ylim(40, 180)\n\nVibration Analysis with Global Normalization\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=vibration_data,\n    Fs=1000,\n    NFFT=1024,\n    noverlap=512,\n    scale='linear',\n    normalize='global'\n)\nplt.colorbar(im, label='Normalized Magnitude')\n\nHigh-Resolution Analysis with Zero-Padding\nfig, ax = plt.subplots(subplot_kw={'projection': 'z_norm'})\nspec, freqs, t, im = ax.specgram(\n    x=signal,\n    Fs=100,\n    NFFT=100,\n    pad_to=512,  # Zero-pad for smoother spectrum\n    noverlap=80,\n    scale='dB'\n)\n\nScale and Normalization Modes\nScale Modes\nMode\tDescription\tUse Case\ndB\tLogarithmic (10log10 for PSD, 20log10 for magnitude)\tLarge dynamic range signals\nlinear\tLinear amplitude\tDirect amplitude comparison\nNormalization Modes (only for scale='linear')\nMode\tDescription\tUse Case\nglobal\tZ/max(Z), preserves relative intensity\tCompare intensity across time\nlocal\tPer-column normalization to [0,1]\tFocus on frequency content over time\nnone\tNo normalization\tRaw spectrogram values\nFrequency Scaling\nfreq_scale\tUnit\tUse Case\n1.0\tHz\tDefault, most signals\n60\tbpm\tHeart rate, respiration rate\n0.001\tkHz\tAudio signals\n\nExample: freq_scale=60 converts 2 Hz → 120 bpm\n\nResolution Guidelines\nFrequency resolution: Δf = Fs / NFFT\nTime resolution: Δt = (NFFT - noverlap) / Fs\nTrade-off: Cannot simultaneously achieve high frequency and time resolution\n\nUse get_specgram_params() to auto-calculate optimal parameters.\n\nInteractive Analysis\nspec, freqs, t, im = ax.specgram(...)\n\ndef on_click(event):\n    if event.xdata and event.inaxes == ax:\n        time_idx = np.argmin(np.abs(t - event.xdata))\n        plt.figure()\n        plt.plot(freqs, spec[:, time_idx])\n        plt.title(f'FFT at t={event.xdata:.2f}s')\n        plt.show()\n\nfig.canvas.mpl_connect('button_press_event', on_click)\n\nApplication Areas\nIMU data: Accelerometer and gyroscope analysis\nPhysiological signals: PPG (heart rate), ECG, respiration\nVibration analysis: Machinery fault diagnosis\nAudio processing: Speech and audio spectrum analysis\nNotes\nAlways call regist_projection() before using projection='z_norm'\nparula_map is recommended for best perceptual uniformity\ndB mode automatically handles log(0) issues\nFor better FFT efficiency, set NFFT to power of 2"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wangyendt/plot",
    "publisherUrl": "https://clawhub.ai/wangyendt/plot",
    "owner": "wangyendt",
    "version": "0.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/plot",
    "downloadUrl": "https://openagent3.xyz/downloads/plot",
    "agentUrl": "https://openagent3.xyz/skills/plot/agent",
    "manifestUrl": "https://openagent3.xyz/skills/plot/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/plot/agent.md"
  }
}