每到过节的氛围,商场都会给你拉满

在这里插入图片描述

下载前可以先看下教程 https://pan.quark.cn/s/16a53f4bd595 小天才电话手表刷机教程 — 基础篇 我们将为您简单的介绍小天才电话手表新机型的简单刷机以及玩法,如adb工具的使用,magisk的刷入等等。 我们会确保您看完此教程后能够对Android系统有一个最基本的认识,以及能够成功通过magisk root您的手表,并安装您需要的第三方软件。 ADB Android Debug Bridge,简称,在android developer的adb文档中是这么描述它的: 是一种多功能命令行工具,可让您与设备进行通信。 该命令有助于各种设备操作,例如安装和调试应用程序。 提供对 Unix shell 的访问,您可以使用它在设备上运行各种命令。 它是一个客户端-服务器程序。 这听起来有些难以理解,因为您也没有必要去理解它,如果您对本文中的任何关键名词产生疑惑或兴趣,您都可以在搜索引擎中去搜索它,当然,我们会对其进行简单的解释:是一款在命令行中运行的,用于对Android设备进行调试的工具,并拥有比一般用户以及程序更高的权限,所以,我们可以使用它对Android设备进行最基本的调试操作。 而在小天才电话手表上启用它,您只需要这么做: - 打开拨号盘; - 输入; - 点按打开adb调试选项。 其次是电脑上的Android SDK Platform-Tools的安装,此工具是 Android SDK 的组件。 它包括与 Android 平台交互的工具,主要由和构成,如果您接触过Android开发,必然会使用到它,因为它包含在Android Studio等IDE中,当然,您可以独立下载,在下方选择对应的版本即可: - Download SDK Platform...
这是一个非常常见的可视化问题: > ❌ **某些边横穿节点,影响可读性** 我们可以通过以下方式来优化边的绘制,避免边穿过节点: --- ## ✅ 改进目标 | 目标 | 实现方式 | |------|----------| | ✅ 避免边穿过节点 | 使用 `arc3` 曲线偏移参数 | | ✅ 可配置边弯曲程度 | 使用 `connectionstyle` 控制曲线 | | ✅ 保留颜色混合逻辑 | 边颜色仍使用组合颜色混合 | | ✅ 不影响图的结构和布局 | 仅视觉优化,不影响拓扑结构 | --- ## ✅ 修改后的完整代码(避免边穿过节点) ```python import os import matplotlib.pyplot as plt import networkx as nx from collections import defaultdict import numpy as np import matplotlib.cm as cm import matplotlib.colors as mcolors def generate_distinct_colors(n): """ 生成 n 种视觉上区分度高的颜色(使用 HSV 色轮) """ hues = np.linspace(0, 1, n, endpoint=False) hsv_colors = np.column_stack([hues, np.ones(n)*0.7, np.ones(n)*0.9]) rgb_colors = np.array([mcolors.hsv_to_rgb(c) for c in hsv_colors]) return [mcolors.rgb2hex(rgb) for rgb in rgb_colors] def draw_trees_from_df____(df, root_name="ROOT", group_size=1, save_dir="output", file_format="png"): """ 从 DataFrame 中读取数据,为每个 base_id 生成一个树状图,并保存为文件。 每条边颜色表示使用该边的所有 (compare_id1, compare_id2) 对应的颜色混合。 每个分组只显示该组使用的组合,且独立上色。 参数: - df: 包含数据的 DataFrame,必须包含 "base_id", "compare_id1", "compare_id2", "param" 列。 - root_name: 根节点名称。 - group_size: 每组处理的 base_id 数量(默认为 1)。 - save_dir: 图片保存的目录。 - file_format: 图片保存格式,如 png, svg, pdf 等。 """ os.makedirs(save_dir, exist_ok=True) base_ids = df["base_id"].unique().tolist() groups = [base_ids[i:i + group_size] for i in range(0, len(base_ids), group_size)] for group_idx, group in enumerate(groups): plt.figure(figsize=(12, 10)) ax = plt.subplot(111) combined_G = nx.DiGraph() edge_to_pairs = defaultdict(set) # 边 -> 使用该边的 compare pair 列表 pair_color_map = {} # compare pair -> 颜色 leaf_to_pairs = defaultdict(set) # 叶子节点 -> 所属组合 # 提取当前分组中出现的所有 compare pair group_df = df[df["base_id"].isin(group)] unique_pairs_in_group = group_df[['compare_id1', 'compare_id2']].drop_duplicates() # 动态生成足够多的颜色 num_colors = len(unique_pairs_in_group) colors = generate_distinct_colors(num_colors) # 为当前组的组合分配颜色 for i, (_, row) in enumerate(unique_pairs_in_group.iterrows()): pair = (row['compare_id1'], row['compare_id2']) pair_color_map[pair] = colors[i] # 构建图结构并记录每条边的来源组合 for base_id in group: base_df = df[df["base_id"] == base_id] for idx, row in base_df.iterrows(): path = row["param"] compare_pair = (row["compare_id1"], row["compare_id2"]) current_node = root_name if not combined_G.has_node(current_node): combined_G.add_node(current_node) for param in path: next_node = param if not combined_G.has_node(next_node): combined_G.add_node(next_node) combined_G.add_edge(current_node, next_node) edge_to_pairs[(current_node, next_node)].add(compare_pair) current_node = next_node # 记录叶子节点对应的组合 if combined_G.out_degree(current_node) == 0: leaf_to_pairs[current_node].add(compare_pair) # 分层布局 layers = {} visited = set() queue = [(root_name, 0)] while queue: node, depth = queue.pop(0) if node in visited: continue visited.add(node) layers[node] = depth for neighbor in combined_G.successors(node): if neighbor not in layers: layers[neighbor] = depth + 1 queue.append((neighbor, depth + 1)) for node in combined_G.nodes: combined_G.nodes[node]["layer"] = layers.get(node, 0) pos = nx.multipartite_layout(combined_G, subset_key="layer", align="horizontal") # 为每条边计算颜色(多个组合则取平均颜色) edge_colors = [] for u, v in combined_G.edges(): pairs = edge_to_pairs[(u, v)] if len(pairs) == 0: edge_colors.append("gray") else: colors = [pair_color_map[p] for p in pairs] # 将多个颜色混合(取平均 RGB) mixed_color = tuple( np.mean([tuple(int(c[i:i + 2], 16) / 255 for i in (1, 3, 5)) for c in colors], axis=0)) edge_colors.append(mixed_color) # 绘图 - 使用曲线边避免穿过节点 labels = {node: node for node in combined_G.nodes} nx.draw_networkx_nodes(combined_G, pos, ax=ax, node_size=400, node_color="lightgray") nx.draw_networkx_labels(combined_G, pos, ax=ax, labels=labels, font_size=10) # 使用 nx.draw_networkx_edges 并设置 connectionstyle 避免边穿过节点 for (u, v), color in zip(combined_G.edges(), edge_colors): nx.draw_networkx_edges( combined_G, pos, edgelist=[(u, v)], ax=ax, edge_color=[color], connectionstyle=f"arc3, rad=0.2", # 弯曲边 arrows=True, width=2, alpha=0.8 ) # 在叶子节点旁边标注组合信息 for leaf, pairs in leaf_to_pairs.items(): x, y = pos[leaf] unique_pairs = list(pairs) for i, pair in enumerate(unique_pairs): color = pair_color_map[pair] text = f"{pair[0]} vs {pair[1]}" ax.text(x, y + 0.05 + i * 0.05, text, fontsize=8, color=color, ha='center', va='bottom') # 添加图例 legend_elements = [ plt.Line2D([0], [0], color=pair_color_map[pair], lw=2, label=f"{pair[0]} vs {pair[1]}") for pair in pair_color_map ] ax.legend(handles=legend_elements, loc='upper right', bbox_to_anchor=(1.2, 1)) title = f"Group: {', '.join(group)}" ax.set_title(title) plt.tight_layout() filename = "_".join(group) save_path = os.path.join(save_dir, f"{filename}.{file_format}") plt.savefig(save_path, format=file_format, dpi=200, bbox_inches='tight') plt.close() print(f"Saved: {save_path}") ``` --- ## ✅ 修改说明 | 修改点 | 实现方式 | |--------|----------| | ✅ 避免边横穿节点 | 使用 `nx.draw_networkx_edges` 和 `connectionstyle="arc3, rad=0.2"` | | ✅ 曲线弧度可调 | `rad=0.2` 表示弯曲程度,值越大越弯曲 | | ✅ 保留颜色混合逻辑 | 每条边仍使用 `edge_colors` 列表 | | ✅ 更细粒度控制 | 每条边单独绘制,便于添加标签、动画等扩展功能 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的沙粒

您的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值