In [9]:
import numpy as np
from numpy import pi
import matplotlib.colors
import plotly.graph_objects as go
import plotly
plotly.offline.init_notebook_mode()
In [10]:
def hsv_colorscale(S=1, V=1, ty=1):
# S saturation in [0,1]
# V value (brightness in [0,1])
# ty a key that can take two values: 1, when the argument belongs to [-pi, pi) is mapped to the HSV colorscale,
# 2, [0, 2*pi)
if S < 0 or S > 1 or V < 0 or V > 1:
raise ValueError('Parameters S (saturation), V (value, brightness) must be in [0,1]')
if ty == 1:
argument = np.array([-pi, -5*pi/6, -2*pi/3, -3*pi/6, -pi/3, -pi/6, 0,
pi/6, pi/3, 3*pi/6, 2*pi/3, 5*pi/6, pi])
H = argument/(2*np.pi)+1
H = np.mod(H,1) # Hue
elif ty == 2:
argument = np.array([ 0, pi/6, pi/3, 3*pi/6, 2*pi/3, 5*pi/6, pi,
7*pi/6, 4*pi/3, 3*pi/2, 5*pi/3, 11*pi/6, 2*pi])
H = argument/(2*np.pi)
else:
raise ValueError("The key ty can get only the value 1 or 2")
Sat = S*np.ones_like(H)
Val = V*np.ones_like(H)
HSV = np.dstack((H, Sat, Val))
RGB = matplotlib.colors.hsv_to_rgb(HSV)
colormap = (255* np.squeeze(RGB)).astype(int)
#Define and return the Plotly hsv colorscale adapted to polar coordinates for complex valued functions
step_size = 1/(colormap.shape[0]-1)
#return [[round(k*step_size, 3), 'rgb'+str((int(c[0]), int(c[1]), int(c[2])))] for k, c in enumerate(colormap)]
return [[round(k*step_size, 3), f'rgb{tuple(c)}'] for k, c in enumerate(colormap)]
Example of HSV colorscale:
In [11]:
mpl_hsv = hsv_colorscale(V=0.95)
mpl_hsv
Out[11]:
Define two HSV colorscales, one for each branch:
In [12]:
pl_hsv1 = hsv_colorscale(S=1, V=0.95, ty=1)
pl_hsv2 = hsv_colorscale(S=1, V=0.95, ty=2)
In [13]:
rho = np.linspace(0, 1.0, 40)
phi = np.linspace(-np.pi, np.pi, 200)
rho, phi = np.meshgrid(rho,phi)
X = rho*np.cos(phi)
Y = rho*np.sin(phi)
Z = X + 1j * Y
r = np.absolute(Z)
argument = np.angle(Z)
wmod = r**0.5
argument /= 2# argument of w=sqrt[2](z) ; argument in [-pi/2, pi/2)
realf = wmod * np.cos(argument)
fig = go.Figure(go.Surface(x=X, y=Y, z=realf,
colorscale=pl_hsv1,
surfacecolor= argument,
cmin=-pi, cmax=pi,
showscale=False))
argument += 2* pi / 2# argument for the second branch; argument in [-pi/2+pi, pi/2+pi)=[pi/2, 3 pi/2]
realf = wmod * np.cos(argument)
fig.add_surface(x=X, y=Y, z=realf,
colorscale=pl_hsv2,
surfacecolor=np.copy(argument),
cmin=0, cmax=2*pi,
showscale=False)
plot_title = 'Riemann surface Re(sqrt(z))), hsv colored<br> according to the argument values on each branch'
fig.update_layout(title_text=plot_title,
title_x=0.5,
font=dict(family='Balto'),
width=600,
height=600)
fig.update_scenes(xaxis_title='Re(z)',
yaxis_title='Im(z)',
zaxis_title='Re(f(z))')
In [14]:
from IPython.core.display import HTML
def css_styling():
styles = open("./custom.css", "r").read()
return HTML(styles)
css_styling()
Out[14]: