简体   繁体   English

平滑地绘制二维点

[英]plot scattered points in 2d smoothly

Primary question: 主要问题:

I wrote a small ray-tracing code. 我写了一个小的光线跟踪代码。 It's called forward ray-tracing, so rays are actually created at the source, travel to the one and only mirror and are reflected. 这称为前向光线跟踪,因此实际上是在光源处创建了光线,然后行进到唯一的一面镜子并被反射。 Subsequently i calculate the intersection of each ray with a plane of my choice i call the detector. 随后,我计算出每条射线与我选择的平面的交点,我将其称为检测器。 And what i get on the detector, printing each hit as a pixel, is a scatter plot of (x,y)'s. 我在检测器上得到的,以像素为单位打印的每个命中点都是(x,y)的散点图。 Like this one: 像这个:

import matplotlib.pyplot as plt
import numpy as np
import random

x = np.zeros(1000)
y = np.zeros(1000)
for i in range(len(x)):
    x[i] = random.random()
    y[i] = random.random()

plt.plot(x,y,'k,')
plt.show()

Now i'm looking for a way to represent the density distribution of the hits (the intensity) as a smooth image, like this one. 现在,我正在寻找一种将击打的密度分布(强度)表示为平滑图像的方法,就像这样

So the gray-scale of each pixel should correspond to the density in the surrounding patch. 因此,每个像素的灰度应与周围斑块中的密度相对应。 But everything that looks like what i need is for 3d-arrays like z=f(x,y). 但是所有看起来像我需要的东西都是用于z = f(x,y)的3d数组。

Also tried hexbin(), but it's not smooth enough and for very small bins it gets too slow and only resembles what i have anyway. 还尝试了hexbin(),但是它不够平滑,对于非常小的垃圾箱,它变得太慢,并且无论如何也仅类似于我的东西。

So is there anything i could use? 那有什么我可以使用的吗?

Secondary question: 次要问题:

I somehow need to add another dimension, because i'm interested in the parallelism of the incident rays. 我不知何故需要添加另一个维度,因为我对入射光线的并行性感兴趣。 One option is to define it as follows: 一种选择是将其定义如下:

  1. calculating a + a*b, where: 计算+ a * b,其中:

a = the angle between the incident ray and the detector normal a =入射射线与检测器法线之间的角度

b = the angle between the incident ray and the yz-plane (the rays are travelling roughly parallel to this plane) b =入射光线与yz平面之间的角度(光线大致平行于该平面传播)

  1. mean value of this quantity 该数量的平均值

  2. deviation from the mean value for each hit 每次点击均值偏离平均值

I thought of incorporating both of these informations in one plot by adding colour to the gray-scale. 我想通过将颜色添加到灰度图中将这两种信息合并到一个图中。 Is this feasible? 这可行吗?

I'm new to programming, any hint, explanation or alternative idea will be much appreciated. 我是编程的新手,任何提示,解释或其他想法将不胜感激。

I don't think you can get away with making a 2d image, just like you mentioned... you need the 3rd dimension to describe the intensity of signal at (x, y). 正如您提到的那样,我认为您无法摆脱制作2D图像的麻烦……您需要第3维来描述(x,y)处的信号强度。 Here's just a quick and dirty example: 这只是一个简单而肮脏的例子:

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np


# just creating random data with a bunch of 2d gaussians

def gauss2d(x, y, a, x0, y0, sx, sy):
    return a * (np.exp(-((x - x0) / sx)**2 / 2.)
                * np.exp(-((y - y0) / sy)**2 / 2.))

imsize = 1000
im = np.zeros((imsize, imsize), dtype=float)

ng = 50
x0s = imsize * np.random.random(ng)
y0s = imsize * np.random.random(ng)
sxs = 100. * np.random.random(ng)
sys = sxs #100. * np.random.random(ng)
amps = 100 + 100 * np.random.random(ng)

for x0, y0, sx, sy, amp in zip(x0s, y0s, sxs, sys, amps):
    nsig = 5.
    xlo, xhi = int(x0 - nsig * sx), int(x0 + nsig * sx)
    ylo, yhi = int(y0 - nsig * sy), int(y0 + nsig * sy)

    xlo = xlo if xlo >= 0 else 0
    xhi = xhi if xhi <= imsize else imsize
    ylo = ylo if ylo >= 0 else 0
    yhi = yhi if yhi <= imsize else imsize

    nx = xhi - xlo
    ny = yhi - ylo

    imx = np.tile(np.arange(xlo, xhi, 1), ny).reshape((ny, nx))
    imy = np.tile(np.arange(ylo, yhi, 1), nx).reshape((nx, ny)).transpose()

    im[ylo:yhi, xlo:xhi] += gauss2d(imx, imy, amp, x0, y0, sx, sy)


plt.imshow(im, cmap=cm.gray)

plt.show()

Basically you treat the data like a 2d image from CCD, each pixel containing the signal strength. 基本上,您将数据视为来自CCD的2d图像,每个像素都包含信号强度。

(I would actually add that depending on what in data you are trying to highlight, you might want to use scatter plot but vary the size/opacity of points to show your information... it really depends what you are trying to achieve.) (我实际上要补充一点,根据您要突出显示的数据内容,您可能要使用散点图,但要改变点的大小/不透明度以显示信息……这实际上取决于您要实现的目标。)

I don't actually understand exactly what you want to plot from ray intensity, but if you are taking about the a ray hitting the image at an angle, you need to compute the projected intensity of the ray onto the plane. 我实际上并不确定要从射线强度绘制什么,但是如果要使射线以一定角度撞击图像,则需要计算射线在平面上的投影强度。 And that's a different question from how you plot with Matplotlib. 这与您如何使用Matplotlib进行绘图是一个不同的问题。

I guess your primary question involves two main steps: First, computing the density function for the scatter points, and second actually plotting it. 我想您的主要问题涉及两个主要步骤:首先,计算散射点的密度函数,然后实际绘制它。 So, if you have a function z = f(x,y), where z is the estimated density at point (x,y), you could use the matplotlib methods you have already researched. 因此,如果您有一个函数z = f(x,y),其中z是在点(x,y)处的估计密度,则可以使用已经研究过的matplotlib方法。

As for the first step, I would suggest to have a look at the kernel density estimation routines in scipy.stats.kde . 至于第一步,我建议看看scipy.stats.kde中的内核密度估计例程。 Basically you do 基本上你会

density = scipy.stats.gaussian_kde(scatterpoints)

and then can evaluate the density for each point from 然后可以从中评估每个点的密度

z = density([x,y])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM