mathplotlib imshow复杂的2D数组

Pro*_*ala 11 matplotlib complex-numbers multidimensional-array

有没有什么好的方法如何在Mathplotlib中将复数的二维数组绘制成图像?

将复数的大小映射为"亮度"或"饱和度"并将相位映射为"Hue"非常有意义(无论如何Hue只不过是RBG颜色空间中的相位). http://en.wikipedia.org/wiki/HSL_and_HSV

但据我所知,imshow只接受标量值,然后使用某些色阶进行映射.没有什么比投影真实的RGB图片更好的了吗?

我很容易实现一个版本,它接受3个浮点数的元组(向量)的二维数组或形状浮点数的ndarray [:,:,3].我想这通常是usefful功能.它对于绘制真实的RGB colord图像(例如从OpenCL输出的纹理)也很有用

Hoo*_*ked 7

该库mpmath用于matplotlib生成复杂平面的精美图像.在复杂的平面上,你通常关心极点,因此函数的参数给出了颜色(因此极点会产生螺旋).极大或极小值的区域由饱和度控制.来自文档:

默认情况下,复数参数(相位)显示为颜色(色调),幅度显示为亮度.您还可以提供自定义颜色功能(颜色).此函数应采用复数作为输入,并返回包含0.0-1.0范围内的浮点数的RGB 3元组.

例:

import mpmath
mpmath.cplot(mpmath.gamma, points=100000)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

另一个显示zeta函数,平凡零点和临界条带的例子:

import mpmath
mpmath.cplot(mpmath.zeta, [-45,5],[-25,25], points=100000)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Hoo*_*ked 7

即使你不知道 numpy和matplotlib 的原始函数,mpmath你也可以调整你的绘图代码.如果你知道的功能,看我原来的答复使用.mpmath.cplot

from colorsys import hls_to_rgb

def colorize(z):
    n,m = z.shape
    c = np.zeros((n,m,3))
    c[np.isinf(z)] = (1.0, 1.0, 1.0)
    c[np.isnan(z)] = (0.5, 0.5, 0.5)

    idx = ~(np.isinf(z) + np.isnan(z))
    A = (np.angle(z[idx]) + np.pi) / (2*np.pi)
    A = (A + 0.5) % 1.0
    B = 1.0 - 1.0/(1.0+abs(z[idx])**0.3)
    c[idx] = [hls_to_rgb(a, b, 0.8) for a,b in zip(A,B)]
    return c
Run Code Online (Sandbox Code Playgroud)

从这里,您可以绘制任意复杂的numpy数组:

N = 1000
A = np.zeros((N,N),dtype='complex')
axis_x = np.linspace(-5,5,N)
axis_y = np.linspace(-5,5,N)
X,Y = np.meshgrid(axis_x,axis_y)
Z = X + Y*1j

A = 1/(Z+1j)**2 + 1/(Z-2)**2

# Plot the array "A" using colorize
import pylab as plt
plt.imshow(colorize(A), interpolation='none',extent=(-5,5,-5,5))
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


nad*_*pez 7

这与@Hooked代码差不多,但速度要快得多.

import numpy as np
from numpy import pi
import pylab as plt
from colorsys import hls_to_rgb

def colorize(z):
    r = np.abs(z)
    arg = np.angle(z) 

    h = (arg + pi)  / (2 * pi) + 0.5
    l = 1.0 - 1.0/(1.0 + r**0.3)
    s = 0.8

    c = np.vectorize(hls_to_rgb) (h,l,s) # --> tuple
    c = np.array(c)  # -->  array of (3,n,m) shape, but need (n,m,3)
    c = c.swapaxes(0,2) 
    return c

N=1000
x,y = np.ogrid[-5:5:N*1j, -5:5:N*1j]
z = x + 1j*y

w = 1/(z+1j)**2 + 1/(z-2)**2
img = colorize(w)
plt.imshow(img)
plt.show()
Run Code Online (Sandbox Code Playgroud)

  • @Adarain 或者我们将第 15 行从 `c = c.swapaxes(0,2)` 更改为 `c = c.transpose(1,2,0)` (2认同)