Source code for visual.plots_macros

from __future__ import annotations

from typing import Sequence, Any, List
from io import BytesIO
import base64
import matplotlib.pyplot as plt
from adjustText import adjust_text


[docs] def create_scatter_plot_encoded_image( x_values: Sequence[float], y_values: Sequence[float], labels: Sequence[Any] | None = None, x_label: str = "X", y_label: str = "Y", title: str | None = None, ) -> str: """ Create a scatter plot and return it as a base64-encoded PNG data URI. Labels are automatically adjusted to reduce overlaps using the adjustText library. Args: x_values: Sequence of x-axis coordinate values. y_values: Sequence of y-axis coordinate values. labels: Optional sequence of labels for each point. Defaults to None. x_label: Label for the x-axis. Defaults to "X". y_label: Label for the y-axis. Defaults to "Y". title: Optional title for the plot. Defaults to None. Returns: str: Base64-encoded PNG image as a data URI (data:image/png;base64,...). Raises: ValueError: If x_values and y_values have different lengths. ValueError: If labels are provided but have a different length than x_values. """ x_values = list(x_values) y_values = list(y_values) if len(x_values) != len(y_values): raise ValueError("x_values and y_values must have the same length") if labels is not None and len(labels) != len(x_values): raise ValueError("labels must have the same length as x_values and y_values") fig, ax = plt.subplots(figsize=(9, 6), dpi=160) ax.scatter( x_values, y_values, s=50, alpha=0.85, edgecolors="black", linewidths=0.7, zorder=3, ) texts = [] if labels is not None: for x, y, label in zip(x_values, y_values, labels): text = ax.text( x, y, str(label), fontsize=9, ha="center", va="center", zorder=4, bbox={ "boxstyle": "round,pad=0.18", "facecolor": "white", "edgecolor": "none", "alpha": 0.75, }, ) texts.append(text) adjust_text( texts, x=x_values, y=y_values, ax=ax, expand=(1.2, 1.4), force_text=(0.4, 0.6), force_static=(0.2, 0.4), arrowprops={ "arrowstyle": "-", "lw": 0.5, "alpha": 0.5, }, ) ax.set_xlabel(x_label, fontsize=10) ax.set_ylabel(y_label, fontsize=10) if title is not None: ax.set_title(title, fontsize=12, pad=12) ax.grid(True, alpha=0.25, linewidth=0.8) ax.set_axisbelow(True) ax.spines["top"].set_visible(False) ax.spines["right"].set_visible(False) ax.margins(x=0.08, y=0.12) fig.tight_layout() png_buffer = BytesIO() fig.savefig( png_buffer, format="png", dpi=300, bbox_inches="tight", pad_inches=0.2, ) plt.close(fig) png_buffer.seek(0) encoded_png = base64.b64encode(png_buffer.getvalue()).decode("utf-8") return f"data:image/png;base64,{encoded_png}"
[docs] def create_graph_degree_distribution_encoded_image( degrees: List[int], bins: int = 20, title: str | None = None, log_scale: bool = False, ) -> str: """ Create a degree distribution histogram and return it as a base64-encoded PNG data URI. Args: degrees: List of degree values for all nodes in the network. bins: Number of histogram bins. Defaults to 20. title: Optional title for the plot. Defaults to None. log_scale: If True, apply logarithmic scale to the y-axis. Defaults to False. Returns: str: Base64-encoded PNG image as a data URI (data:image/png;base64,...). """ fig, ax = plt.subplots(figsize=(8, 6)) ax.hist( degrees, bins=bins, edgecolor="black", alpha=0.75, ) ax.set_xlabel(None) ax.set_ylabel("Number of nodes") ax.set_title(title) ax.grid(True, axis="y", alpha=0.3) if log_scale: ax.set_yscale("log") fig.tight_layout() png_buffer = BytesIO() fig.savefig(png_buffer, format="png", dpi=300, bbox_inches="tight") plt.close(fig) png_buffer.seek(0) encoded_png = base64.b64encode(png_buffer.getvalue()).decode("utf-8") return f"data:image/png;base64,{encoded_png}"
[docs] def create_barplot_encoded_image( edges: List[str], values: List[float], title: str | None = None, y_label: str | None = None, x_labebl: str | None = None, ) -> str: """ Create a horizontal bar plot and return it as a base64-encoded PNG data URI. Args: edges: List of labels for each bar (displayed on y-axis). values: List of values corresponding to each bar. title: Optional title for the plot. Defaults to None. y_label: Optional label for the y-axis. Defaults to None. x_labebl: Optional label for the x-axis (note: typo in parameter name). Defaults to None. Returns: str: Base64-encoded PNG image as a data URI (data:image/png;base64,...). """ fig, ax = plt.subplots(figsize=(10, 6)) ax.barh(edges, values) ax.set_xlabel(x_labebl) ax.set_ylabel(y_label) ax.set_title(title) ax.invert_yaxis() ax.grid(True, axis="x", alpha=0.3) fig.tight_layout() png_buffer = BytesIO() fig.savefig(png_buffer, format="png", dpi=300, bbox_inches="tight") plt.close(fig) png_buffer.seek(0) encoded_png = base64.b64encode(png_buffer.getvalue()).decode("utf-8") return f"data:image/png;base64,{encoded_png}"