2013-06-11 6 views
5

क्या मैथप्लॉटिब में छवि के रूप में जटिल संख्याओं की 2 डी सरणी को साजिश करने का कोई अच्छा तरीका है?mathplotlib imshow complex 2D array

जटिल संख्या की परिमाण को "चमक" या "संतृप्ति" और चरण "ह्यू" के रूप में मानचित्रित करने के लिए बहुत अधिक समझदारी होती है (वैसे भी ह्यू आरबीजी रंग स्थान में चरण से कुछ और नहीं है)। http://en.wikipedia.org/wiki/HSL_and_HSV

लेकिन जहां तक ​​मुझे पता है कि imshow केवल स्केलर मान स्वीकार करता है जिसे बाद में कुछ रंगों का उपयोग करके मैप किया जाता है। वास्तविक आरजीबी चित्रों की साजिश रुकने जैसी कोई बात नहीं है?

मुझे लगता है कि यह केवल एक संस्करण को लागू करना आसान होगा जो 3 फ्लोटिंग पॉइंट नंबरों के 2 डी सरणी (वेक्टर) या आकार की फ्लोट के ndarray को स्वीकार करता है [:,:, 3]। मुझे लगता है कि यह आम तौर पर उपयोगफुल सुविधा होगी। वास्तविक आरजीबी कॉलर्ड छवियों को साजिश करने के लिए यह भी उपयोगी होगा, जैसे ओपनसीएल

+0

इस उत्तर को देखें एक अन्य प्रश्न के लिए: http://stackoverflow.com/a/17113417/907575 –

उत्तर

4

इस लगभग @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() 
7

लाइब्रेरी mpmath जटिल विमान की सुंदर छवियों का उत्पादन करने के लिए matplotlib का उपयोग करता है। जटिल विमान पर आप आमतौर पर ध्रुवों की परवाह करते हैं, इसलिए फ़ंक्शन का तर्क रंग देता है (इसलिए ध्रुव एक सर्पिल बनाते हैं)। संतृप्ति द्वारा अत्यधिक बड़े या छोटे मूल्यों के क्षेत्र नियंत्रित होते हैं। डॉक्स से:

डिफ़ॉल्ट रूप से, जटिल तर्क (चरण) रंग (रंग) के रूप में दिखाया गया है और परिमाण चमक के रूप में दिखाई देता है। आप कस्टम रंग फ़ंक्शन (रंग) भी प्रदान कर सकते हैं। इस फ़ंक्शन को इनपुट के रूप में जटिल संख्या लेनी चाहिए और एक आरजीबी 3-टुपल को श्रेणी 0.0-1.0 में फ़्लोट करना चाहिए।

उदाहरण:

import mpmath 
mpmath.cplot(mpmath.gamma, points=100000) 

enter image description here

एक और उदाहरण zeta function, तुच्छ शून्य और critical strip दिखा:

import mpmath 
mpmath.cplot(mpmath.zeta, [-45,5],[-25,25], points=100000) 

enter image description here

+0

यह अच्छा लग रहा है, हालांकि यह केवल उन कार्यों को साजिश करने के लिए है जहां मुझे विश्लेषणात्मक नुस्खे पता है। यह मेरा मामला नहीं है। मुझे जटिल डेटा को डिक्रेट नमूनाकरण के साथ साजिश करने के लिए कुछ चाहिए जो मैंने पाठ फ़ाइल से पढ़ा और 2 डी narray में स्टोर किया। मेरे पास इस डेटा के लिए स्पष्ट फ़ंक्शनल पर्चे नहीं है जिसे किसी भी बिंदु पर नमूना दिया जा सकता है। –

5

mpmath से साजिश कोड को अनुकूलित करना आप एक numpy array प्लॉट कर सकते हैं भले ही आप मूल कार्य को numpy और matplotlib के साथ नहीं जानते हैं। यदि आप see my original answermpmath.cplot का उपयोग कर फ़ंक्शन को जानते हैं, तो see my original answer

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 

यहां से, आप एक मनमाना जटिल 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() 

enter image description here

+0

बहुत बहुत धन्यवाद! यह काफी धीमा है, इसलिए बेहतर होगा अगर ऐसा फ़ंक्शन सीधे हार्डकोडेड नुकीला होगा (मेरा मतलब है कि अन्य सरणी संचालन के समान कुछ भी है - बिना पाइथन लूप द्वारा सरणी पर पुनरावृत्त किए बिना)। लेकिन महत्वपूर्ण यह है कि यह काम करता है। –

+0

@ProkopHapala वास्तव में अधिकांश काम _is_ numpy के साथ किया गया है, 'hls_to_rgb' पर कॉल को छोड़कर जिसे आप शायद वेक्टरराइज़ कर सकते हैं। आप अंक 'एन' की संख्या को बदलकर इसे बहुत अधिक तेजी से बना सकते हैं, गति एन^2 के आनुपातिक होनी चाहिए। – Hooked

3

आप colorsys.hls_to_rgb, जिसके बारे में 10 गुना तेजी से है के बजाय matplotlib.colors.hsv_to_rgb उपयोग कर सकते हैं!

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.colors import hsv_to_rgb 
import time 

def Complex2HSV(z, rmin, rmax, hue_start=90): 
    # get amplidude of z and limit to [rmin, rmax] 
    amp = np.abs(z) 
    amp = np.where(amp < rmin, rmin, amp) 
    amp = np.where(amp > rmax, rmax, amp) 
    ph = np.angle(z, deg=1) + hue_start 
    # HSV are values in range [0,1] 
    h = (ph % 360)/360 
    s = 0.85 * np.ones_like(h) 
    v = (amp -rmin)/(rmax - rmin) 
    return hsv_to_rgb(np.dstack((h,s,l))) 

यहाँ @nadapez द्वारा उठाया जवाब की विधि है: नीचे परिणाम देखने

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

t0 = time.time() 
img = Complex2HSV(z, 0, 4) 
t1 = time.time() 
print "Complex2HSV method: "+ str (t1 - t0) +" s" 

t0 = time.time() 
img = colorize(z) 
t1 = time.time() 
print "colorize method: "+ str (t1 - t0) +" s" 

:

from colorsys import hls_to_rgb 
def colorize(z): 
    r = np.abs(z) 
    arg = np.angle(z) 

    h = (arg + np.pi)/(2 * np.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 

परीक्षण 1024 * 1024 2darray के साथ दो विधि से परिणाम इसका परिणाम मेरे पुराने लैपटॉप पर:

Complex2HSV method: 0.250999927521 s 
colorize method: 2.03200006485 s