sfstoolbox/sfs-python

Sound field plot using pyplot.imshow()

narahahn opened this issue · 2 comments

When pyplot.imshow() is used without extent option, the pixels are shown on integer coordinates.
imshow

The position of the pixels can be adjusted by using extent as we are doing in sfs.plot.soundfield. Below I choose extent=[-1, 2, -1, 1]
imshow-extent

All pixels are fit into the defined range. As a result, the plot is a bit smaller than it should be. You can see that the pixels are off the grid points. For instance, the lower left pixel is supposed to be centered at [-1, 1] but is now inside the defined range.
In most cases, this won't be a big problem for high-resolution plots. But if we want to draw lines or add patches on top of the plot, it might be noticeable. Here is an example.
pulsating-sphere-pressure

The origin of the sound field and the center of the circle do not match exactly.

One way to circumvent this issue is changing the extent values,
extent=[xmin, xmax, ymin, ymax]
to
extent=[xmin - dx / 2, xmax + dx / 2, ymin - dy / 2, ymax + dy / 2]
where dx and dy are the spacing of the grid in the respective coordinates.
imshow-corrected-extent

Alternatively, we can use pyplot.pcolormesh instead.
It might be preferred since it takes the x- and y-axes (let say x and y) as input arguments, so there will be no scaling issue.
A downside for our use case is that the pixels are not shown at (x[i], y[i]) but inside a rectangle defined by (x[i], x[i+1], y[i], y[i+1]). So the x and y should have one more element than the dimensions of the data. Otherwise, the image will be cropped like this.
pcolormesh

Therefore, x should be appended by x[-1] + dx and shifted by -dx / 2 ( and y correspondingly).

x = np.append(x, x[-1] + dx) - dx / 2
y = np.append(y, y[-1] + dy) - dy / 2

pcolormesh-append-shift

  • Is it worth fixing this problem?
  • Both solutions need dx and dy to put the pixels at the right positions.

Is it worth fixing this problem?

Yes!

AFAIK, the advantage of imshow() is the possibility to have interpolation.

Unless there is a good reason to switch to pcolormesh(), I would stay with imshow() for now.

I think we should manipulate the extent in sfs.plot.soundfield() in the way you described.

Fixed by #96.