|
1 | 1 | """ pyplots.ai |
2 | 2 | qrcode-basic: Basic QR Code Generator |
3 | | -Library: seaborn 0.13.2 | Python 3.13.11 |
4 | | -Quality: 91/100 | Created: 2026-01-07 |
| 3 | +Library: seaborn 0.13.2 | Python 3.14.3 |
| 4 | +Quality: 91/100 | Updated: 2026-04-07 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import matplotlib.pyplot as plt |
8 | 8 | import numpy as np |
9 | 9 | import qrcode |
10 | 10 | import seaborn as sns |
| 11 | +from matplotlib.colors import ListedColormap |
| 12 | +from matplotlib.patches import FancyBboxPatch |
11 | 13 |
|
12 | 14 |
|
13 | | -# Generate QR code |
14 | | -qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=1, border=4) |
15 | | -qr.add_data("https://pyplots.ai") |
| 15 | +# Configure seaborn with consolidated set_theme |
| 16 | +sns.set_theme(context="poster", style="white", font_scale=1.0) |
| 17 | + |
| 18 | +# Generate QR code with proper encoding |
| 19 | +encoded_url = "https://pyplots.ai" |
| 20 | +qr = qrcode.QRCode(version=None, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=1, border=4) |
| 21 | +qr.add_data(encoded_url) |
16 | 22 | qr.make(fit=True) |
17 | 23 |
|
18 | | -# Get QR code as numpy array (0 = white, 1 = black in QR convention) |
19 | | -# We need to convert the QR image to a matrix |
20 | | -qr_matrix = np.array(qr.get_matrix(), dtype=int) |
| 24 | +# Convert QR matrix to numpy array |
| 25 | +qr_matrix = np.array(qr.get_matrix(), dtype=np.uint8) |
| 26 | +n_modules = qr_matrix.shape[0] - 8 # exclude quiet zone (border=4 each side) |
| 27 | + |
| 28 | +# Branded color scheme using seaborn palette |
| 29 | +brand_dark = sns.color_palette("dark:#1a1a2e", 1)[0] |
| 30 | +brand_accent = sns.color_palette("muted")[0] # seaborn muted blue for accents |
| 31 | +qr_cmap = ListedColormap(["#ffffff", brand_dark]) |
21 | 32 |
|
22 | | -# Create figure - square format for QR code |
| 33 | +# Plot on square canvas |
23 | 34 | fig, ax = plt.subplots(figsize=(12, 12)) |
24 | 35 |
|
25 | | -# Use seaborn heatmap to display QR code matrix |
26 | | -# Invert colors: QR codes are black on white, so we use a reversed colormap |
27 | 36 | sns.heatmap( |
28 | 37 | qr_matrix, |
29 | 38 | ax=ax, |
30 | | - cmap="Greys", |
| 39 | + cmap=qr_cmap, |
| 40 | + vmin=0, |
| 41 | + vmax=1, |
31 | 42 | square=True, |
32 | 43 | cbar=False, |
33 | 44 | xticklabels=False, |
|
36 | 47 | linecolor="white", |
37 | 48 | ) |
38 | 49 |
|
39 | | -# Remove axes for clean QR code appearance |
| 50 | +# Remove all chrome |
| 51 | +sns.despine(ax=ax, left=True, bottom=True, top=True, right=True) |
40 | 52 | ax.set_xlabel("") |
41 | 53 | ax.set_ylabel("") |
42 | | -ax.set_title("qrcode-basic · seaborn · pyplots.ai", fontsize=24, pad=20) |
| 54 | +ax.tick_params(left=False, bottom=False) |
| 55 | + |
| 56 | +# Annotate finder patterns with subtle highlight boxes |
| 57 | +finder_size = 7 |
| 58 | +border = 4 |
| 59 | +finder_positions = [ |
| 60 | + (border, border, "top-left"), |
| 61 | + (border, qr_matrix.shape[1] - border - finder_size, "top-right"), |
| 62 | + (qr_matrix.shape[0] - border - finder_size, border, "bottom-left"), |
| 63 | +] |
| 64 | +for row, col, _label in finder_positions: |
| 65 | + rect = FancyBboxPatch( |
| 66 | + (col - 0.3, row - 0.3), |
| 67 | + finder_size + 0.6, |
| 68 | + finder_size + 0.6, |
| 69 | + boxstyle="round,pad=0.2", |
| 70 | + linewidth=1.5, |
| 71 | + edgecolor=brand_accent, |
| 72 | + facecolor="none", |
| 73 | + alpha=0.5, |
| 74 | + ) |
| 75 | + ax.add_patch(rect) |
| 76 | + |
| 77 | +# Finder pattern annotation arrow pointing to top-right finder |
| 78 | +fp_x = qr_matrix.shape[1] - border - finder_size / 2 |
| 79 | +fp_y = border + finder_size / 2 |
| 80 | +ax.annotate( |
| 81 | + "Finder Pattern", |
| 82 | + xy=(fp_x, fp_y), |
| 83 | + xytext=(fp_x + 2.5, fp_y - 5), |
| 84 | + fontsize=13, |
| 85 | + fontweight="medium", |
| 86 | + color=brand_accent, |
| 87 | + ha="center", |
| 88 | + arrowprops={"arrowstyle": "->", "color": brand_accent, "lw": 1.5}, |
| 89 | +) |
43 | 90 |
|
44 | | -# Remove axis spines for cleaner look |
45 | | -for spine in ax.spines.values(): |
46 | | - spine.set_visible(False) |
| 91 | +# Quiet zone label on left side |
| 92 | +ax.text( |
| 93 | + 1.2, |
| 94 | + qr_matrix.shape[0] / 2, |
| 95 | + "Quiet Zone", |
| 96 | + fontsize=12, |
| 97 | + color="#888888", |
| 98 | + rotation=90, |
| 99 | + ha="center", |
| 100 | + va="center", |
| 101 | + fontstyle="italic", |
| 102 | +) |
| 103 | + |
| 104 | +# Title with strong typographic hierarchy |
| 105 | +ax.set_title("qrcode-basic · seaborn · pyplots.ai", fontsize=28, fontweight="bold", pad=24, color="#1a1a2e") |
| 106 | + |
| 107 | +# Subtitle with encoded content and technical details — tighter spacing below QR |
| 108 | +fig.text( |
| 109 | + 0.5, |
| 110 | + 0.03, |
| 111 | + f"Encodes: {encoded_url} · Error Correction: M (15%) · Version {qr.version} · {n_modules}×{n_modules} modules", |
| 112 | + ha="center", |
| 113 | + va="bottom", |
| 114 | + fontsize=15, |
| 115 | + color="#666666", |
| 116 | + fontstyle="italic", |
| 117 | +) |
47 | 118 |
|
48 | | -plt.tight_layout() |
| 119 | +plt.subplots_adjust(bottom=0.07, top=0.93) |
49 | 120 | plt.savefig("plot.png", dpi=300, bbox_inches="tight", facecolor="white") |
0 commit comments