plot_fxy2.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """Draw a z = BesselJ(x,y) surface with a custom color map
  2. and a custom scalar bar with labels in radians"""
  3. import numpy as np
  4. from scipy import special
  5. from scipy.special import jn_zeros
  6. from vedo import ScalarBar3D, Line, show, settings
  7. from vedo.colors import color_map, build_lut
  8. from vedo.pyplot import plot
  9. Nr = 1
  10. Nθ = 3
  11. settings.default_font = "Theemim"
  12. settings.interpolate_scalars_before_mapping = False
  13. axes_opts = dict(
  14. xtitle="x", ytitle="y", ztitle="|f(x,y)|",
  15. xlabel_rotation=90, ylabel_rotation=90, zlabel_rotation=90,
  16. xtitle_rotation=90, ytitle_rotation=90, zaxis_rotation=45,
  17. ztitle_offset=0.03,
  18. )
  19. def custom_lut_surface(name, vmin=0, vmax=1, N=256):
  20. # Create a custom look-up-table for the surface
  21. table = []
  22. x = np.linspace(vmin, vmax, N)
  23. for i in range(N):
  24. rgb = color_map(i, name, 0, N-1)
  25. table.append([x[i], rgb])
  26. return build_lut(table)
  27. def custom_table_scalarbar(name):
  28. # Create a custom table of colors and labels for the scalarbar
  29. table = []
  30. x = np.linspace(-np.pi,np.pi, 401)
  31. labs = ["-:pi" , "-3:pi/4", "-:pi/2", "-:pi/4", "0",
  32. "+:pi/4", "+:pi/2", "+3:pi/4","+:pi"]
  33. for i in range(401):
  34. rgb = color_map(i, name, 0, 400)
  35. if i%50 == 0:
  36. table.append([x[i], rgb, 1, labs[i//50]])
  37. else:
  38. table.append([x[i], rgb])
  39. return table, build_lut(table)
  40. ######################################################################
  41. def f(x, y):
  42. d2 = x**2 + y**2
  43. if d2 > 1:
  44. return np.nan
  45. else:
  46. r = np.sqrt(d2)
  47. θ = np.arctan2(y, x)
  48. kr = jn_zeros(Nθ, 4)[Nr]
  49. return special.jn(Nθ, kr * r) * np.exp(1j * Nθ * θ)
  50. p1 = plot(
  51. lambda x,y: np.abs(f(x,y)),
  52. xlim=[-1, 1], ylim=[-1, 1],
  53. bins=(100, 100),
  54. show_nan=False,
  55. axes=axes_opts,
  56. )
  57. # Unpack the 0-element (the surface of the plot) to customize it
  58. msh = p1[0].lighting('glossy')
  59. pts = msh.points # get the points
  60. zvals = pts[:,2] # get the z values
  61. θvals = [np.angle(f(*p[:2])) for p in pts] # get the phases
  62. lut = custom_lut_surface("hsv", vmin=-np.pi, vmax=np.pi)
  63. msh.cmap(lut, θvals) # apply the color map
  64. table, lut = custom_table_scalarbar("hsv")
  65. line = Line((1,-1), (1,1)) # a dummy line to attach the scalarbar to
  66. line.cmap("hsv", [0, 1])
  67. scbar = ScalarBar3D(
  68. line,
  69. title=f"N_r ={Nr}, N_θ ={Nθ}, phase :theta in radians",
  70. label_rotation=90,
  71. categories=table,
  72. c='black',
  73. )
  74. # convert the scalarbar to a 2D object and place it to the bottom
  75. scbar = scbar.clone2d([-0.6,-0.7], size=0.2, rotation=-90, ontop=True)
  76. # Set a specific camera position and orientation (shift-C to see it)
  77. cam = dict(
  78. position=(3.88583, 0.155949, 3.88584),
  79. focal_point=(0, 0, 0), viewup=(-0.7, 0, 0.7), distance=5.4,
  80. )
  81. show(p1, scbar, __doc__, camera=cam).close()