我正在制作一个基于Python的简单程序,它将graphviz图作为输出。我想使用描述程序数据的自定义节点。一旦你有了图像,使用自定义节点很简单,但是我无法找到一种方便的方法来生成我想要的图像。
具体来说,我希望节点是圆形,其面积代表一个测量值,但其梯度代表该值的不确定性。使用由某些数学程序(例如sagemath)产生的等高线图似乎是合理的,但这些倾向于制作未缩放的方形图像。或者,图像处理程序上的梯度函数似乎很难与严格的高斯函数相关联。
理想情况下,我想按照这个伪代码的方式写一个函数......
def make_node_image(measured_value, std_dev):
mean_circle_radius = sqrt(measured_value/pi)
image_circle_radius = sqrt((measured_value + 2*std_dev)/pi)
gradient_amplitude = 1/(std_dev*sqrt(2*pi))
gradient_fade = e^(-(r-mean_circle_radius)^2/(2*std_dev^2))
image_gradient = gradient_amplitude*gradient_fade
***generate_image_from_gradient***
***scale_and_clip_image_to_image_circle_radius***
return image
两个星号是我需要帮助的地方;我很感激任何建议,谢谢!
答案 0 :(得分:2)
实现此目的的一种方法是使用matplotlib
,就像您在代码中所建议的那样。要做到这一点,我会
image_gradient
。 figure
,其形状为大小,单位为英寸,与圆的半径(image_circle_radius
)相关,为此,您需要记住图中的点数。英寸(fig.dpi
)axes
(fig.add_axes([0,0,1,1],frameon=False, xticks=[], yticks=[]
)imshow
将数组绘制为图像。 set_clip_path()
方法剪切AxesImage
调用创建的imshow
。 这种方法的灵感来自matplotlib example。
这是尝试做出规定的事情:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as path
import matplotlib.patches as patches
pi = np.pi
sqrt = np.sqrt
exp = np.exp
def make_node_image(measured_value, std_dev, coverage="0.96",imageID=1):
DPI = 100
TODPI=1
MINSIZE = 50 # in DPI
MAXSIZE = 400 # in DPI
MAXAMPLITUDE = .005
# make radius,std_dev values in grid units
mean_circle_radius = int(sqrt(measured_value/pi)/TODPI)
image_circle_radius = int(sqrt((measured_value + 2*std_dev)/pi)/TODPI)
if image_circle_radius < MINSIZE:
raise Exception("image_circle_radius too small!")
if image_circle_radius > MAXSIZE:
raise Exception("image_circle_radius too large!")
grid_std_dev = std_dev/TODPI
gradient_amplitude = 1/(std_dev*sqrt(2*pi))/MAXAMPLITUDE
gradient_fade = np.zeros([2*image_circle_radius,
2*image_circle_radius])
for ix in range(2*image_circle_radius):
for iy in range(2*image_circle_radius):
r = sqrt((ix-image_circle_radius)**2
+(iy-image_circle_radius)**2)
gradient_fade[ix,iy] = exp(
-(r-mean_circle_radius)**2
/(2*grid_std_dev**2))
image_gradient = gradient_amplitude*gradient_fade
fig = plt.figure(figsize=(2*image_circle_radius/DPI,
2*image_circle_radius/DPI),dpi=DPI)
ax = fig.add_axes([0,0,1,1],frameon=True, xticks=[], yticks=[])
#***generate_image_from_gradient***
im = ax.imshow(image_gradient,vmin=0,vmax=1)
patch = patches.Circle((image_circle_radius,image_circle_radius),
radius=image_circle_radius,fc='white')
#***scale_and_clip_image_to_image_circle_radius***
im.set_clip_path(patch)
name = 'circImage%d.png'%imageID
fig.savefig(name)
return name
make_node_image(90000*pi,100)
这导致:
gradient_fade
的矢量化方法,虽然我手边还不知道它是什么。