|
| 1 | +import matplotlib.pyplot as plt |
| 2 | +import matplotlib.patches as mpatches |
| 3 | + |
| 4 | + |
| 5 | +markdown_table = """ |
| 6 | +| From \\ To | String | Boolean | Char | Byte | Short | Int | Long | Long256 | Float | Double | Decimal | Date | Timestamp | Symbol | Binary | |
| 7 | +| --------- | ------ | ------- | ----- | ----- | ----- | ----- | ----- | ------- | ----- | ------ | ------- | ----- | --------- | ------ | ------ | |
| 8 | +| String | | `E` | `E*` | `E` | `E` | `I` | `I` | `I` | `I` | `I` | `E` | `I` | `I` | `I` | `N/A` | |
| 9 | +| Boolean | `I` | | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `N/A` | `I` | `I` | `I` | `N/A` | |
| 10 | +| Char | `I` | `N/A` | | `E*` | `I` | `I` | `I` | `I` | `I` | `I` | `N/A` | `I` | `I` | `I` | `N/A` | |
| 11 | +| Byte | `I` | `E*` | `I` | | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `N/A` | |
| 12 | +| Short | `I` | `E*` | `E*` | `I` | | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `I` | `N/A` | |
| 13 | +| Int | `E` | `E*` | `E*` | `E*` | `E*` | | `I` | `I` | `I*` | `I` | `I` | `I` | `I` | `I` | `N/A` | |
| 14 | +| Long | `E` | `E*` | `E*` | `E*` | `E*` | `E*` | | `I` | `E*` | `I*` | `I` | `I` | `I` | `E` | `N/A` | |
| 15 | +| Long256 | `E` | `E*` | `E*` | `E*` | `E*` | `E*` | `E*` | | `E*` | `E*` | `N/A` | `E*` | `E*` | `E*` | `N/A` | |
| 16 | +| Float | `E` | `N/A` | `E*` | `E*` | `E*` | `I*` | `I*` | `I*` | | `I` | `E*` | `I*` | `I*` | `I` | `N/A` | |
| 17 | +| Double | `E` | `N/A` | `E*` | `E*` | `E*` | `E*` | `I*` | `I*` | `E*` | | `E*` | `I*` | `I*` | `E` | `N/A` | |
| 18 | +| Decimal | `E` | `N/A` | `N/A` | `E!` | `E!` | `E!` | `E!` | `N/A` | `E*` | `E*` | | `N/A` | `N/A` | `N/A` | `N/A` | |
| 19 | +| Date | `E` | `E*` | `E*` | `E*` | `E*` | `E*` | `I` | `I` | `E*` | `I*` | `N/A` | | `I` | `E` | `N/A` | |
| 20 | +| Timestamp | `E` | `E*` | `E*` | `E*` | `E*` | `E*` | `I` | `I` | `E*` | `I*` | `N/A` | `I*` | | `E` | `N/A` | |
| 21 | +| Symbol | `I` | `E` | `E` | `E` | `E` | `E` | `I` | `I` | `E` | `I` | `N/A` | `I` | `I` | | `N/A` | |
| 22 | +| Binary | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | `N/A` | |
| 23 | +""" |
| 24 | + |
| 25 | +# --- Parse Markdown into matrix --- |
| 26 | +lines = [line.strip() for line in markdown_table.strip().split("\n") if line.strip()] |
| 27 | +header = [h.strip() for h in lines[0].split("|")[1:-1]] # remove leading/trailing pipe |
| 28 | +rows = [] |
| 29 | + |
| 30 | +matrix = {} |
| 31 | +for line in lines[2:]: # skip header + separator |
| 32 | + parts = [p.strip().strip("`") for p in line.split("|")[1:-1]] |
| 33 | + row_name, values = parts[0], parts[1:] |
| 34 | + matrix[row_name] = dict(zip(header[1:], values)) # map To-cols to values |
| 35 | + rows.append(row_name) |
| 36 | + |
| 37 | +cols = header[1:] |
| 38 | + |
| 39 | +# --- Color mapping --- |
| 40 | +color_map = { |
| 41 | + "": "white", |
| 42 | + "I": "#a6d96a", # implicit |
| 43 | + "E": "#fdae61", # explicit |
| 44 | + "I*": "#313695", # implicit precision loss |
| 45 | + "E*": "#d73027", # explicit precision loss |
| 46 | + "E!": "#e08214", # explicit warning |
| 47 | + "N/A": "#7f7f7f" # grey |
| 48 | +} |
| 49 | + |
| 50 | +# --- Plot --- |
| 51 | +fig, ax = plt.subplots(figsize=(5, 4)) |
| 52 | + |
| 53 | +for i, row in enumerate(rows): |
| 54 | + for j, col in enumerate(cols): |
| 55 | + val = matrix[row].get(col, "") |
| 56 | + ax.add_patch(plt.Rectangle( |
| 57 | + (j, i), 1, 1, |
| 58 | + facecolor=color_map.get(val, "white"), |
| 59 | + edgecolor="black", linewidth=0.5 |
| 60 | + )) |
| 61 | + |
| 62 | +# Configure ticks |
| 63 | +ax.set_xticks([i + 0.5 for i in range(len(cols))]) |
| 64 | +ax.set_yticks([i + 0.5 for i in range(len(rows))]) |
| 65 | +ax.set_xticklabels(cols, rotation=90) |
| 66 | +ax.set_yticklabels(rows) |
| 67 | + |
| 68 | +# Put X axis labels at the top |
| 69 | +ax.xaxis.tick_top() |
| 70 | + |
| 71 | +ax.set_xlim(0, len(cols)) |
| 72 | +ax.set_ylim(0, len(rows)) |
| 73 | +ax.invert_yaxis() |
| 74 | +ax.set_aspect("equal") |
| 75 | + |
| 76 | +# Axis labels |
| 77 | +ax.set_xlabel("TO", labelpad=20) |
| 78 | +ax.xaxis.set_label_position("top") |
| 79 | + |
| 80 | +ax.set_ylabel("FROM", labelpad=20) |
| 81 | +ax.yaxis.set_label_position("left") |
| 82 | + |
| 83 | +# Legend centered at bottom |
| 84 | +legend_elements = [ |
| 85 | + mpatches.Patch(facecolor="#a6d96a", edgecolor="black", label="Implicit"), |
| 86 | + mpatches.Patch(facecolor="#fdae61", edgecolor="black", label="Explicit"), |
| 87 | + mpatches.Patch(facecolor="#313695", edgecolor="black", label="Implicit (precision loss)"), |
| 88 | + mpatches.Patch(facecolor="#d73027", edgecolor="black", label="Explicit (precision loss)"), |
| 89 | + mpatches.Patch(facecolor="#7f7f7f", edgecolor="black", label="N/A") |
| 90 | +] |
| 91 | +ax.legend(handles=legend_elements, |
| 92 | + bbox_to_anchor=(0.5, -0.05), loc="upper center", ncol=3, frameon=False) |
| 93 | + |
| 94 | +# Save directly to file |
| 95 | +path = "../static/images/docs/castmap.jpg" |
| 96 | +plt.savefig(path, dpi=300, bbox_inches="tight") |
| 97 | +plt.close() |
| 98 | +print("file written to: " + path) |
0 commit comments