我编写了一个Python脚本f(n),它生成一个整体的列表,然后是一个线段的第三个,然后是第九个,然后是第27个等。如何将其转换为图形 - 理想情况下我可以放大和缩小并导航?
我想绘制第一行,然后绘制第三行,然后是第九行,然后是第九行,以及第27行,以及类似于Cantor集合构建的熟悉方式。
f标记在Cantor集合构造的每个阶段保留的区间的片段,具有一些值(假设它为了参数而将它们编号)并且它标记所有被删除的片段为零,以下列格式标记:
[row-number,element_number,label]
其中label是每个段的一些参数,让我们说现在它将从1开始的已删除部分编号并将所有删除的部分标记为零。
所以输出:
F(0)= [[0,0,1]]
F(1)= [[0,0,1],[1,0,2],[1,1,0],[1,2,3]]
F(3)= [[0,0,1],[1,0,2],[1,1,0],[1,2,3],[2,0,4],[ 2,1,0],[2,2,5],[2,3,0],[2,4,0],[2,5,0],[2,6,6],[2, 7,0],[2,8,7]]
等
所以要明确的是,要绘制前n行的图形,我不需要使用f(x小于n),因为f(n)足以列出每一行中的段。
所有必要的数据都在那里,因为我们可以读取行号l并从中可以定位它的高度以及推断段的长度为1/3 ^ l,并且我们有元素的element_number e所以我们可以把它放在e / 3 ^ l的位置,我们有标签放在它的中心e /(2 * 3 ^(l-1))
我已经安装了networkx,mathplotlib,我也可以导出一个gexf,但我很难找到一种方法(对于一个noob程序员)来绘制这些标记的条形或段。任何帮助将不胜感激。
答案 0 :(得分:1)
我根本不懂“标签”。但是通过递归地走水平,很容易产生一个cantor情节。
import numpy as np
import matplotlib.pyplot as plt
line = [0,1]
depth = 5
def divide(line, level=0):
plt.plot(line,[level,level], color="k", lw=5, solid_capstyle="butt")
if level < depth:
s = np.linspace(line[0],line[1],4)
divide(s[:2], level+1)
divide(s[2:], level+1)
divide(line)
plt.gca().invert_yaxis()
plt.show()
<小时/> 在这里标记线条并不是直截了当的,因为线条的递归放置与所需标签的顺序不同。一个解决方法是为每一行放置一个标签,然后对标签进行排序;然后从排序列表中给出每个号码。
import numpy as np
import matplotlib.pyplot as plt
line = [0,1]
depth = 5
labels=[]
def divide(line, level=0):
plt.plot(line,[level,level], color="k", lw=5, solid_capstyle="butt")
label = plt.annotate("",xy=(np.mean(line),level), xytext=(0,5),
textcoords="offset points", ha="center", color="crimson")
labels.append(label)
if level < depth:
s = np.linspace(line[0],line[1],4)
divide(s[:2], level+1)
divide(s[2:], level+1)
divide(line)
labels.sort(key=lambda x: x.xy[::-1])
for i, label in enumerate(labels):
label.set_text(i+1)
plt.gca().invert_yaxis()
plt.show()
请注意,行越小,文本的可读性越差。因此,标注较低的小线只在放大时才有意义。