有没有一种使用Python生成渐变位图的简单方法?
我正在生成一个简单的、基于Python的程序,该程序生成graphviz图形作为输出。我想使用自定义节点来描述程序中的数据。一旦有了图像,使用自定义节点就足够简单了,但是我很难找到一种方便的方法来生成我想要的图像 具体来说,我希望节点是圆,其面积表示测量值,但梯度表示该值的不确定性。使用一些数学程序(例如)生成的等高线图似乎是合理的,但这些程序往往会生成未缩放的方形图像。或者,图像处理程序上的梯度函数似乎很难与严格的高斯函数相关联 理想情况下,我想按照伪代码的思路编写一个函数有没有一种使用Python生成渐变位图的简单方法?,python,image,matplotlib,graphviz,Python,Image,Matplotlib,Graphviz,我正在生成一个简单的、基于Python的程序,该程序生成graphviz图形作为输出。我想使用自定义节点来描述程序中的数据。一旦有了图像,使用自定义节点就足够简单了,但是我很难找到一种方便的方法来生成我想要的图像 具体来说,我希望节点是圆,其面积表示测量值,但梯度表示该值的不确定性。使用一些数学程序(例如)生成的等高线图似乎是合理的,但这些程序往往会生成未缩放的方形图像。或者,图像处理程序上的梯度函数似乎很难与严格的高斯函数相关联 理想情况下,我想按照伪代码的思路编写一个函数 def make_
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
这两个星号是我需要帮助的地方;如果有任何建议,我将不胜感激,谢谢 实现这一点的一种方法是使用
matplotlib
,正如您在标记中所建议的那样。要做到这一点,我会
图像\u梯度
李>
图形
,其大小以英寸为单位与圆的半径相关(image\u circle\u radius
),您需要记住图形的每英寸点数(fig.dpi
)fig.add_轴([0,0,1,1],frameon=False,xticks=[],yticks=[])
imshow
将阵列绘制为图像set\u clip\u path()
方法剪裁由imshow
调用创建的AxesImage
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)
将numpy导入为np
将matplotlib.pyplot作为plt导入
将matplotlib.path导入为路径
将matplotlib.patches导入为修补程序
pi=np.pi
sqrt=np.sqrt
exp=np.exp
def生成节点图像(测量值,标准偏差,覆盖率=“0.96”,图像ID=1):
DPI=100
TODPI=1
MINSIZE=50(以DPI为单位)
最大尺寸=400英寸DPI
最大振幅=.005
#以网格单位生成半径、标准偏差值
平均圆半径=int(sqrt(测量值/pi)/TODPI)
图像圆半径=整数(sqrt((测量值+2*std\U dev)/pi)/TODPI)
如果图像\圆\半径<最小尺寸:
引发异常(“图像\圆\半径太小!”)
如果图像\圆\半径>最大尺寸:
引发异常(“图像\圆\半径太大!”)
网格标准偏差=标准偏差/TODPI
梯度振幅=1/(标准偏差*sqrt(2*pi))/MaxAmpliance
渐变淡入=np.零([2*图像\圆\半径,
2*图像(圆(半径)])
对于范围内的ix(2*图像\圆\半径):
对于范围内的iy(2*图像\圆\半径):
r=sqrt((ix-图像\圆\半径)**2
+(iy-image_圆_半径)**2)
梯度衰减[ix,iy]=exp(
-(r-平均圆半径)**2
/(2*电网标准开发**2)
图像梯度=梯度振幅*梯度衰减
图=plt.图(图尺寸=(2*图像、圆、半径/DPI),
2*图像\圆\半径/DPI),DPI=DPI)
ax=fig.add_轴([0,0,1,1],frameon=True,xticks=[],yticks=[]))
#***从梯度生成图像***
im=ax.imshow(图像梯度,vmin=0,vmax=1)
面片=面片圆((图像圆半径,图像圆半径),
半径=图像\圆\半径,fc='白色')
#***缩放和剪裁图像到圆半径***
im.设置剪辑路径(补丁)
名称='circImage%d.png'%imageID
图savefig(名称)
返回名称
制作节点图像(90000*pi,100)
这导致:
渐变_fade
,尽管我不知道它是什么我在下面提供了一个答案,但我没有得到参数
覆盖率的要点,以及r
小于平均圆半径的值会发生什么情况。如果我不了解这些要点,我可能错过了最终结果,但我想我得到了您希望的要点。您非常善于观察t、 覆盖率参数最初旨在限制图像半径,但更容易仅在两个标准偏差处切断边界。测量值是物体的质量,因此不能为负。质量测量的概率分布函数不是严格的高斯分布,但不足以确定在这个程序中需要寻址。密度函数在零以下的“尾部”可以用几种方式寻址,但这对我的问题并不重要。这是一个很好的开始,谢谢!我使用了matploblib,但主要是作为python(x,y)的后端,我不太擅长直接使用它。