python画气泡图_python – 在Matplotlib中制作一个非重叠的气泡图(圆形包装)

我目前正在尝试在Matplotlib中制作气泡图,其中气泡不重叠,因此在图表中包装圆圈/气泡,大约类似于this.

我认为可能有用:

>使用x = 1,y = 1绘制第一个数据点

>通过计算给定标量值的气泡半径来随机绘制其他数据点,以避免重叠

但我无法真正实现它,也无法找到任何相关信息.

解决方法:

以下是一种蛮力方法.

您可以首先将所有圆放置在网格上,网格间距可以是任何圆的最大半径的两倍.

m6kLn.png

然后你让圆圈随机行走,并检查每一步中是否有一束陨石的“势能”变小,并且获得的位置是否有效(即没有重叠).

if (e < self.E and self.isvalid(i)):

作为“潜力”,我们可以简单地使用方形径向函数.

self.p = lambda x,y: np.sum((x**2+y**2)**2)

代码:

import numpy as np

import matplotlib.pyplot as plt

# create 10 circles with different radii

r = np.random.randint(5,15, size=10)

class C():

def __init__(self,r):

self.N = len(r)

self.x = np.ones((self.N,3))

self.x[:,2] = r

maxstep = 2*self.x[:,2].max()

length = np.ceil(np.sqrt(self.N))

grid = np.arange(0,length*maxstep,maxstep)

gx,gy = np.meshgrid(grid,grid)

self.x[:,0] = gx.flatten()[:self.N]

self.x[:,1] = gy.flatten()[:self.N]

self.x[:,:2] = self.x[:,:2] - np.mean(self.x[:,:2], axis=0)

self.step = self.x[:,2].min()

self.p = lambda x,y: np.sum((x**2+y**2)**2)

self.E = self.energy()

self.iter = 1.

def minimize(self):

while self.iter < 1000*self.N:

for i in range(self.N):

rand = np.random.randn(2)*self.step/self.iter

self.x[i,:2] += rand

e = self.energy()

if (e < self.E and self.isvalid(i)):

self.E = e

self.iter = 1.

else:

self.x[i,:2] -= rand

self.iter += 1.

def energy(self):

return self.p(self.x[:,0], self.x[:,1])

def distance(self,x1,x2):

return np.sqrt((x1[0]-x2[0])**2+(x1[1]-x2[1])**2)-x1[2]-x2[2]

def isvalid(self, i):

for j in range(self.N):

if i!=j:

if self.distance(self.x[i,:], self.x[j,:]) < 0:

return False

return True

def plot(self, ax):

for i in range(self.N):

circ = plt.Circle(self.x[i,:2],self.x[i,2] )

ax.add_patch(circ)

c = C(r)

fig, ax = plt.subplots(subplot_kw=dict(aspect="equal"))

ax.axis("off")

c.minimize()

c.plot(ax)

ax.relim()

ax.autoscale_view()

plt.show()

hklu0.png

由于这种随机游走性质,找到解决方案需要一点时间(在这种情况下约为10秒);您当然可以使用参数(主要是步骤1000 * self.N的数量,直到解决方案得到修复),看看哪些适合您的需求.

标签:python,matplotlib

来源: https://codeday.me/bug/20190608/1196137.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值