在Manim中使用【GenericGraph】
一,介绍
GenericGraph
是一个用于创建图的类,属于 Manim 库(一个用于数学动画的库)。这个类用于表示和可视化图形结构(图),包括顶点和边。
1.构造函数:
class GenericGraph(vertices, edges, labels=False,
label_fill_color=ManimColor('#000000'),
layout='spring', layout_scale=2, layout_config=None,
vertex_type=<class 'manim.mobject.geometry.arc.Dot'>,
vertex_config=None, vertex_mobjects=None,
edge_type=<class 'manim.mobject.geometry.line.Line'>,
partitions=None, root_vertex=None, edge_config=None)
2.参数说明
-
vertices:
- 类型: 列表或集合
- 描述: 图中的顶点,可以是任意对象的集合,每个对象代表一个图的节点。
-
edges:
- 类型: 列表或集合
- 描述: 图中的边,通常表示为一个二元组的列表,每个二元组代表一条连接两个顶点的边。
-
labels:
- 类型: 布尔值(默认值: False)
- 描述: 是否为顶点添加标签。如果为 True,顶点将显示其标签。
-
label_fill_color:
- 类型: ManimColor
- 描述: 顶点标签的填充颜色,默认为黑色('#000000')。
-
layout:
- 类型: 字符串(默认值: 'spring')
- 描述: 布局算法,用于确定顶点在图中的位置。可选择的值包括 'spring'(弹簧布局)等。
-
layout_scale:
- 类型: 数字(默认值: 2)
- 描述: 布局的缩放因子,影响顶点之间的距离。
-
layout_config:
- 类型: 字典(可选)
- 描述: 布局算法的配置参数,具体参数取决于所选的布局方法。
-
vertex_type:
- 类型: 类(默认值: Dot)
- 描述: 用于绘制顶点的对象类型,默认是 Manim 中的
Dot
类,可以用其他几何对象代替。
-
vertex_config:
- 类型: 字典(可选)
- 描述: 顶点的具体配置,如颜色、大小等。
-
vertex_mobjects:
- 类型: 列表(可选)
- 描述: 用于自定义的顶点对象,允许用户提供特定的绘图对象。
-
edge_type:
- 类型: 类(默认值: Line)
- 描述: 用于绘制边的对象类型,默认是 Manim 中的
Line
类。
-
partitions:
- 类型: 列表(可选)
- 描述: 用于将顶点分组的列表,通常用于分区显示图的不同部分。
-
root_vertex:
- 类型: 可选
- 描述: 如果图是有根的树状结构,可以指定根顶点。
-
edge_config:
- 类型: 字典(可选)
- 描述: 边的具体配置,如颜色、宽度等。
GenericGraph
类是用于在 Manim 中绘制和可视化图形(图)数据结构的工具,可以通过提供 vertices 和 edges 来构建图,并可以通过其他参数自定义顶点和边的样式及布局方式。
二,实际使用
实例1:
from manim import *
class DirafGraphExample01(Scene):
def construct(self):
# 定义顶点
vertices = [0, 1, 2, 3]
# 定义边,表示顶点之间的连接
edges = [(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)]
# 创建 GenericGraph 对象
graph = Graph(
vertices=vertices,
edges=edges,
labels=True, # 显示顶点标签
label_fill_color='#FFFFFF', # 标签颜色为白色
layout='spring', # 使用弹簧布局
layout_scale=3.5, # 布局缩放因子
vertex_type=Dot, # 使用 Dot 类型绘制顶点
vertex_config={"color": BLUE, "radius": 0.5}, # 设置顶点的颜色和半径
edge_type=Line, # 使用 Line 类型绘制边
edge_config={"color": YELLOW, "stroke_width": 2}, # 设置边的颜色和宽度
partitions=None, # 不设置分区
root_vertex=None, # 不设置根顶点
)
# 将图形添加到场景
self.play(Create(graph))
# 保持画面一段时间
self.wait(2)
运行结果:
代码解释:
- 首先,您需要从 Manim 导入相关模块。
- 创建一个名为
GraphExample
的场景类,继承自Scene
。 - 在
construct
方法中定义图的顶点和边。 - 创建
GenericGraph
实例,传入所有参数,包括顶点、边、标签和配置等。 - 使用
self.play(Create(graph))
将图形添加到场景中并显示。 - 使用
self.wait(2)
保持场景信息展示 2 秒钟。
三,GenericGraph使用的的方法
1.GenericGraph._add_edge()方法
1.构造函数和参数解释
_add_edge(edge, edge_type=<class 'manim.mobject.geometry.line.Line'>, edge_config=None)
参数解释:
-
edge
(tuple[Hashable, Hashable])
:- 这代表一条边,由一对顶点标识符组成。这意味着你可以在图中指定哪些顶点之间连接有一条边。如果传递的顶点标识符不存在,该方法将会创建一个新顶点,使用默认设置。
-
edge_type
type[Mobject]
:- 这是一个可选参数,用于指定用于表示边的 Mobject 类。默认值是
Line
,但是可以替换为其他类型的对象,如Arrow
或自定义的边类,以便在场景中使用不同的样式绘制边。
- 这是一个可选参数,用于指定用于表示边的 Mobject 类。默认值是
-
edge_config
(dict | None)
:- 这是一个可选字典,用于传递额外的关键字参数给通过
edge_type
指定的类。这些配置可以用来调整边的颜色、宽度和其他属性。
- 这是一个可选字典,用于传递额外的关键字参数给通过
示例
from manim import *
class Add_edge(Scene):
def construct(self):
# 创建顶点
graph = Graph(
vertices=[1, 2, 3, 4],
edges=[],
layout='spring'
)
# 添加边
graph._add_edge((1, 2), edge_type=Arrow, edge_config={"color": GREEN, "stroke_width": 4})
graph._add_edge((2, 3), edge_type=Arrow, edge_config={"color": GREEN, "stroke_width": 4})
graph._add_edge((3, 4), edge_type=Arrow, edge_config={"color": GREEN, "stroke_width": 4})
graph._add_edge((4, 1), edge_type=Arrow, edge_config={"color": GREEN, "stroke_width": 4})
graph._add_edge((1, 3), edge_type=Arrow, edge_config={"color": RED, "stroke_width": 4})
# 将图形添加到场景
self.play(Create(graph))
# 保持画面一段时间
self.wait(2)
运行结果:
代码解释:
- 创建 Graph 对��:我们创建一个空的图对象。
- 添加边:
- 使用
_add_edge
方法向图中添加边,指定顶点对及其显示类型和设置。 - 例如,我们添加了一条绿色和红色的箭头,连接不同的顶点。
- 使用
- 显示图形:使用
self.play(Create(graph))
将图形添加到场景中并显示。 - 等待:使用
self.wait(2)
缓停画面,使最终结果可见。
2.GenericGraph._add_vertex()方法
1.构造函数和参数解释
构造函数:
_add_vertex(vertex, position=None, label=False, label_fill_color=ManimColor('#000000'),
vertex_type=<class 'manim.mobject.geometry.arc.Dot'>, vertex_config=None,
vertex_mobject=None)[source]
_add_vertex
是一个方法,用于在图形中添加顶点,并具有以下参数:
2.参数解释:
-
vertex
(Hashable)
:- 这是一个唯一的标识符,代表要添加的顶点。该标识符可以是任何可哈希类型(如整数、字符串等),用于区分图中的不同顶点。
-
position
(optional)
:- 这个可选参数定义了顶点在图中的位置。如果未指定,则使用默认的位置。
-
label
(bool)
:- 这是一个布尔值,指示是否为顶点添加标签。如果设置为
True
,则会显示该顶点的标签,标签内容通常是顶点的标识符。
- 这是一个布尔值,指示是否为顶点添加标签。如果设置为
-
label_fill_color
(ManimColor)
:- 这个参数用于设置标签的填充颜色。如果标签被启用,可以使用此参数来调整标签的视觉效果,默认为黑色(
'#000000'
)。
- 这个参数用于设置标签的填充颜色。如果标签被启用,可以使用此参数来调整标签的视觉效果,默认为黑色(
-
vertex_type
(type[Mobject])
:- 这是一个可选参数,用于指定用于显示顶点的 Mobject 类。默认值是
Dot
,但可以替换为其他类型的对象以更改顶点的样式。
- 这是一个可选参数,用于指定用于显示顶点的 Mobject 类。默认值是
-
vertex_config
(dict | None)
:- 这是一个可选字典,用于传递额外的关键字参数给指定的
vertex_type
类,例如设置顶点的颜色、大小或其他属性。
- 这是一个可选字典,用于传递额外的关键字参数给指定的
-
vertex_mobject
(optional)
:- 这个参数允许直接传递一个 Mobject 实例来作为顶点。如果指定了该参数,方法将使用该实例,而不是根据
vertex_type
创建一个新的实例。
- 这个参数允许直接传递一个 Mobject 实例来作为顶点。如果指定了该参数,方法将使用该实例,而不是根据
3.示例:
from manim import *
class Add_vertex01(Scene):
def construct(self):
# 创建一个空的图对象
graph = Graph(
vertices=[1, 2, 3,],
edges=[],
layout='spring'
)
# 添加顶点
graph._add_vertex(vertex='A', position=LEFT, label=True, label_fill_color=WHITE, vertex_type=Dot, vertex_config={"color": BLUE, "radius": 0.5})
graph._add_vertex(vertex='B', position=RIGHT, label=True, label_fill_color=WHITE, vertex_type=Dot, vertex_config={"color": GREEN, "radius": 0.5})
graph._add_vertex(vertex='C', position=UP, label=True, label_fill_color=WHITE, vertex_type=Dot, vertex_config={"color": RED, "radius": 0.5})
# 添加边
graph._add_edge(('A', 'B'), edge_type=Line, edge_config={"color": YELLOW, "stroke_width": 3})
graph._add_edge(('B', 'C'), edge_type=Line, edge_config={"color": YELLOW, "stroke_width": 3})
graph._add_edge(('C', 'A'), edge_type=Line, edge_config={"color": YELLOW, "stroke_width": 3})
# 将图形添加到场景
self.play(Create(graph))
# 保持画面一段时间
self.wait(2)
运行结果:
代码解释:
- 创建 Graph 对象:我们创建一个空的图对象以存储顶点和边。
- 添加顶点:
- 使用
_add_vertex
方法添加标识符为 'A'、'B' 和 'C' 的三个顶点,设置了它们的颜色和半径。 - 标签被启用,并且使用白色填充以便于在不同颜色背景下可见。
- 使用
- 添加边:
- 使用
_add_edge
方法创建边连接这些顶点,定义边的颜色和宽度。
- 使用
- 显示图形:使用
self.play(Create(graph))
将图形添加到场景中并显示。 - 等待:使用
self.wait(2)
暂停画面,使得最终结果可见。
3.GenericGraph._empty_networkx_graph()方法
构造函数和参数解释:
static _empty_networkx_graph()[source]
_empty_networkx_graph
是一个静态方法,通常在一些图形处理库或框架中使用,这里可能指的是 NetworkX,一个用于创建、操作和研究复杂网络的 Python 库。虽然这个函数的具体实现和用途可能因上下文而异,但一般来说,_empty_networkx_graph()
方法用于创建一个空的图形容器。
函数解释
- 功能: 创建并返回一个空的 NetworkX 图形对象,通常用于在之后的操作中添加顶点和边。
- 参数: 该函数通常不需要任何参数,因为它的主要作用是初始化一个空图。
- 返回值: 返回一个空的 NetworkX 图对象,用户可以在其上进行进一步的操作,如添加节点和边。
示例:
import networkx as nx
import matplotlib.pyplot as plt
# 创建一个空的 NetworkX 图
def create_empty_graph():
G = nx.Graph() # 创建一个空图
return G
# 添加节点和边
def add_nodes_and_edges(G):
# 添加节点
G.add_node("A")
G.add_node("B")
G.add_node("C")
G.add_node("D")
# 添加边
G.add_edges_from([("A", "B"), ("B", "C"), ("C", "A"),("D", "A"),("D", "B"),("D", "C")])
# 可视化图形
def visualize_graph(G):
pos = nx.spring_layout(G) # 位置布局
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=16,
font_color='black', font_weight='bold', edge_color='gray', width=2)
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体来显示中文
plt.title("这是一个_empty_networkx_graph()", fontsize=20)
plt.show()
# 主执行代码
if __name__ == "__main__":
G = create_empty_graph() # 创建空图
add_nodes_and_edges(G) # 添加节点和边
visualize_graph(G) # 可视化图形
运行结果:
4.GenericGraph.original__init_()方法
1.构造函数和参数解释;
_original__init__(vertices, edges, labels=False, label_fill_color=ManimColor('#000000'),
layout='spring', layout_scale=2, layout_config=None, vertex_type=<class
'manim.mobject.geometry.arc.Dot'>, vertex_config=None, vertex_mobjects=None, edge_type=
<class 'manim.mobject.geometry.line.Line'>, partitions=None, root_vertex=None,
edge_config=None)
_original__init__
似乎是一个构造函数,可能用于图形或网络可视化的模块,存放于 Manim(一种数学动画制作工具)中。虽然具体实现可能存在于不同的版本或项目中,但我们可以根据参数的命名进行推测。
参数解释
以下是参数的可能含义:
-
vertices: 图的节点列表。通常是一个包含所有节点的集合或列表。
-
edges: 图的边列表。通常是一个包含所有边的集合或列表,其中每条边由连接节点的元组表示。
-
labels: 布尔值,指示是否为节点添加标签。如果为
True
,则会在节点上方显示标记。 -
label_fill_color: 节点标签的填充颜色,可以使用
ManimColor
类型来指定颜色,比如ManimColor('#000000')
表示黑色。 -
layout: 布局方法,可以选择不同的可视化布局,例如
spring
布局(以力导向算法为基础)或其他可能存在的布局方式。 -
layout_scale: 布局缩放因子,用于调整可视化时的整体大小。
-
layout_config: 用于特定布局配置的字典,可根据需要传递布局的详细参数。
-
vertex_type: 节点的类型,默认情况下是
Dot
类,可以定制为其他形状或类型。 -
vertex_config: 各种配置参数,用于节点的样式定义。
-
vertex_mobjects: 自定义节点对象的列表,允许用户使用自定义形状或样式代替默认节点。
-
edge_type: 边的类型,默认情况下是
Line
类,可以定制为其他类型。 -
partitions: 分区定义,通常用于图的分组或聚类,可能在某些算法或布局中有用。
-
root_vertex: 指定根节点,可能用于特定的算法,如树结构可视化。
-
edge_config: 边的样式定义,用于配置边的外观。
示例
from manim import *
class Original__init01(Scene):
def construct(self):
# 定义顶点和边
vertices = ["A", "B", "C", "D", "E"]
edges = [("A", "B"), ("A", "C"), ("B", "D"), ("C", "D"), ("D", "E")]
# 创建图形对象
graph = Graph(
vertices,
edges,
vertex_type=Dot,
edge_type=Line,
layout='spring',
layout_scale=2,
vertex_config={"color": BLUE, "radius": 0.5},
edge_config={"stroke_color": GREEN, "stroke_width": 5},
# 在这里我们只使用必要的参数,不要添加 layout_config
labels=True,
)
# 创建图形
self.play(Create(graph))
self.wait(2)
运行结果:
5.GenericGraph._populate_edge_dict()方法
构造函数和参数:
_populate_edge_dict(edges, edge_type)[source]
_populate_edge_dict
是一个内部方法,用于将边的列表转换为特定字典结构,以方便在图形中处理这些边。虽然具体的实现细节和上下文可能会有所不同,这里是一个通用的解释。
函数目的
该函数的主要目的是根据边的输入(通常由名字或其他唯一标识符组成的元组)生成一个字典,该字典将每个边映射到一个边类型(如图形的线段对象)。这便于后续的图形渲染和数据显示。
参数
-
edges:
- 类型: 列表(list)
- 描述: 包含边的列表,每项通常是一个元组,表示边的连接的两个顶点。例如:
[("A", "B"), ("B", "C")]
。
-
edge_type:
- 类型: 类(class)
- 描述: 指定边的类型,它通常是在图形中表示边的类,比如
Line
类型。这会指导如何创建边的对象实例。
示例:
from manim import *
class Populate_edge_dict(Scene):
def construct(self):
# 定义顶点与边
vertices = ["A", "B", "C"]
edges = [("A", "B"), ("B", "C")]
# 使用 Graph 来展示图结构
graph = Graph(vertices, edges, layout='spring', vertex_type=Dot)
# 动画展示
self.play(Create(graph))
self.wait(2)
6.GenericGraph._remove_edge()和GenericGraph._remove_vertex()方法
1. _remove_edge(edge)
函数目的:_remove_edge
函数的主要目的在于从图形结构中移除指定的边。通常在图形数据结构(如图表或网络图)中,边代表了两个顶点之间的连接,移除边可以改变图形的结构。
参数:
edge
:- 类型: 元组 (tuple)
- 描述: 代表要移除的边,通常是包含连接的两个顶点的元组。例如:
("A", "B")
表示要移除从顶点 A 到顶点 B 的边。
2. _remove_vertex(vertex)
函数目的:_remove_vertex
函数的主要目的在于从图形结构中移除指定的顶点。移除顶点的同时,也会影响与该顶点相关联的边。
参数:
vertex
:- 类型: 任意(根据上下文,一般为字符串或数字)
- 描述: 代表要移除的顶点。例如:
"A"
表示要从图形中移除顶点 A。
示例:
from manim import *
class SimpleGraph01(Scene):
def construct(self):
# 创建一个简单的图
vertices = ["A", "B", "C"]
edges = [("A", "B"), ("B", "C")]
# 使用 Graph 来展示图结构
graph = Graph(vertices, edges, layout='spring', vertex_type=Dot)
self.play(Create(graph))
# 移除边 ("B", "C")
self.remove_edge_and_update(graph, ("B", "C"))
# 移除顶点 "D"
#self.remove_vertex_and_update(graph, "D")
self.wait(2)
def remove_edge_and_update(self, graph, edge):
graph._remove_edge(edge) # 调用内部方法移除边
edge_line = Line(graph.vertices[edge[0]].get_center(), graph.vertices[edge[1]].get_center())
# 移除边的动画
self.play(FadeOut(edge_line))
self.play(ApplyMethod(graph.vertices[edge[0]].set_color, WHITE))
self.play(ApplyMethod(graph.vertices[edge[1]].set_color, WHITE))
def remove_vertex_and_update(self, graph, vertex):
graph._remove_vertex(vertex) # 调用内部方法移除顶点
# 移除顶点的动画
target_dot = graph.vertices[vertex]
self.play(FadeOut(target_dot))
# 更新图形的其他部分(如与该顶点相连的边)
for edge in graph.edges:
if vertex in edge:
self.remove_edge_and_update(graph, edge)
7.GenericGraph.add_edges()方法
构造函数:
add_edges(*edges, edge_type=<class 'manim.mobject.geometry.line.Line'>,
edge_config=None, **kwargs)[source]
add_edges
是 Manim 中用于在图形中添加边的一个方法。它通常用于在图表或图形结构中创建连接两点的线。
解释构造函数和参数
-
*edges
: 这是一个可变参数,允许您传入一个或多个边的定义。边通常是一个由两个顶点表示的元组,例如(vertex1, vertex2)
。 -
edge_type
: 这是一个类参数,默认值是Line
。它指定要用于创建边的对象类型。您可以将其设置为任何其他类型的 Manim 形状,例如Arrow
或DashedLine
。 -
edge_config
: 这是一个可选参数,用于传递边的配置字典。您可以在此字典中设置边的颜色、宽度等属性。该参数是None
时,边将使用默认样式。 -
**kwargs
: 这是一个可变参数,允许您传递其他关键字参数,通常用于初始化边。
9.GenericGraph.add_vertices()
10.GenericGraph.change_layout()
构造函数:
change_layout(layout='spring', layout_scale=2, layout_config=None, partitions=None, root_vertex=None)[source]
示例:
from manim import *
class ChangeGraphLayout(Scene):
def construct(self):
G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3), (3, 4), (4, 5)],
layout={1: [-2, 0, 0], 2: [-1, 0, 0], 3: [0, 0, 0],
4: [1, 0, 0], 5: [2, 0, 0]}
)
self.play(Create(G))
self.play(G.animate.change_layout("circular"))
self.wait()
运行结果:
11.GenericGraph.from_networkx()
示例:
import networkx as nx
nxgraph = nx.erdos_renyi_graph(14, 0.5)
class ImportNetworkxGraph(Scene):
def construct(self):
G = Graph.from_networkx(nxgraph, layout="spring", layout_scale=3.5)
self.play(Create(G))
self.play(*[G[v].animate.move_to(5*RIGHT*np.cos(ind/7 * PI) +
3*UP*np.sin(ind/7 * PI))
for ind, v in enumerate(G.vertices)])
self.play(Uncreate(G))
运行结果:
12.GenericGraph.remove_edges()
13.GenericGraph.remove_vertices()