Created
January 10, 2026 06:57
-
-
Save nickva/5e9854e42f9d1a54f9089126716153a7 to your computer and use it in GitHub Desktop.
Render CouchDB's new _time_seq response as a histogram
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # Render _time_seq response as a histogram using matplotlib | |
| # Run as: | |
| # http $DB/db/_time_seq | ~/scripts/time_seq_histogram_mplib.py | |
| import json, sys | |
| from datetime import datetime | |
| import matplotlib.pyplot as plt | |
| import matplotlib.dates as mdates | |
| SECONDS_PER_DAY = 86400 | |
| BAR_COLOR = (0.8, 0.15, 0.16) | |
| def load_data(infile): | |
| data = json.load(infile) | |
| time_seq = data.get('time_seq', {}) | |
| for key in time_seq: | |
| node_data = time_seq[key] | |
| for node_key in node_data: | |
| return node_data[node_key] | |
| return [] | |
| def histogram(data): | |
| if not data: | |
| return | |
| tstamps = [] | |
| counts = [] | |
| for tstamp_str, count in data: | |
| try: | |
| dt = datetime.fromisoformat(tstamp_str.replace('Z', '+00:00')) | |
| tstamps.append(dt) | |
| counts.append(count) | |
| except: | |
| print(f"Warning: Could not parse timestamp: {tstamp_str}") | |
| continue | |
| if not tstamps: | |
| print("No valid timestamps found") | |
| return | |
| bar_widths = [] | |
| for i in range(len(tstamps)): | |
| if i < len(tstamps) - 1: | |
| # matplotlib uses days for datetime | |
| dt = (tstamps[i+1] - tstamps[i]).total_seconds() / SECONDS_PER_DAY | |
| bar_widths.append(dt - 1200/SECONDS_PER_DAY) | |
| else: | |
| # Let's use 3h for last bin | |
| bar_widths.append(3*3600/SECONDS_PER_DAY) | |
| fig, ax = plt.subplots(figsize=(12, 6)) | |
| ax.bar(tstamps, counts, width=bar_widths, align='edge', color=BAR_COLOR, alpha=0.7, edgecolor='black') | |
| ax.set_xticks(tstamps) | |
| ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%dT%Hh')) | |
| plt.xticks(rotation=-45, ha='left', fontsize=7) | |
| ax.grid(True, alpha=0.4, axis='y') | |
| ax.annotate('$Now$', xy=(0.97, 0), ha='left', va='top', xycoords='axes fraction', fontweight='bold', fontsize=9) | |
| plt.tight_layout() | |
| plt.show() | |
| def main(): | |
| try: | |
| if not sys.stdin.isatty(): | |
| data = load_data(sys.stdin) | |
| else: | |
| print("Usage:") | |
| print(" cat <file_path> | python3 time_seq_histogram3.py") | |
| return | |
| if not data: | |
| return | |
| histogram(data) | |
| except FileNotFoundError as e: | |
| print(f"Error: File not found: {e}") | |
| except json.JSONDecodeError as e: | |
| print(f"Error: Invalid JSON format: {e}") | |
| except Exception as e: | |
| print(f"Error: {e}") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment