CoCalc Shared FilesNewer Stuff / Newer Bits of the Graphical Appendix / new_plot3d_syntax.sage
Authors: Gregory Bard, Harald Schilly, ℏal Snyder
Views : 11
1# Wrappers for 3d Plotting, especially for complex valued functions
4# Authors:
5# * Gregory Bard <[email protected]>
6# * Harald Schilly <[email protected]>
7
8def new_plot3d( f, xmin, xmax, ymin, ymax, zmin, zmax, **kwargs ):
9    r"""
10    This function provides a 3D plot of a function z=f(x,y) but in
11    a restricted domain given by xmin < x < xmax, ymin < y < ymax, and
12    zmin < z < zmax. It also computes the correct aspect ratio to make
13    the 3D plot appear in a cube. Note, if the widths of the intervals
14    on x, y and z, are not the same length, then this will distort
15    angles and some distances. Yet, this usually produces a very visually
16    appealling 3D graph.
17
18    Example:
19
20    var("x y z")
21    new_plot3d( x^3-y^4, -2,2,-2,2,-4,4 )
22
23    The options color, plot_points, mesh, opacity, and aspect_ratio
24    are available from implicit_plot3d(). Moreover, the options viewer,
25    width, and possibly others are available from show().
26    """
27
28    assert xmin < xmax
29    assert ymin < ymax
30    assert zmin < zmax
31
32    xwide = xmax - xmin
33    ywide = ymax - ymin
34    zwide = zmax - zmin
35
36    # This line of code will see if mesh has been specified by the calling
37    # code. If it has *not* been specified, it will be set to True.
38    kwargs['mesh'] = kwargs.get('mesh', True )
39
40    # This line of code will see if plot_points has been specified by the
41    # calling code. If it has *not* been specified, it will be set to 25.
42    kwargs['plot_points'] = kwargs.get('plot_points', 25)
43
44    # This line of code will see if color has been specified by the
45    # calling code. If it has *not* been specified, it will be set to seagreen.
46    kwargs['color'] = kwargs.get('color', 'seagreen')
47
48    # This line of code will see if the aspect_ratio has been specified by
49    # the calling code. If it has *not* been specified, it will be set
50    # to [1/xwide, 1/ywide, 1/zwide ]
51    kwargs['aspect_ratio'] = kwargs.get('aspect_ratio', [1/xwide, 1/ywide, 1/zwide] )
52
53    var("x y z")
54
55    P = implicit_plot3d( z == f(x,y), (x,xmin,xmax), (y,ymin,ymax), (z,zmin,zmax), **kwargs )
56
57    return P
58
59def new_complex_plot3d( f, xmin, xmax, ymin, ymax, zmin, zmax, style, **kwargs ):
60    """This plots a function whose sole input is a complex number, and whose sole
61    output is a complex number. There are many ways to plot such a function, and
62    they are chosen with the parameter style.
63
64    The options for style are 'magnitude', 'real', 'imaginary', 'argument', or 'mixed'.
65    Also 'phase' is a synonym for 'argument'.
66
67    Consider the function to be plotted as f(s) = f(x+iy). To be clear, the input to
68    the complex-function f is s=x+iy. The 3D plot has an x-axis, a y-axis, and a z-axis.
69
70    The x-axis is always the real part of the input, and the y-axis is always the
71    imaginary part of the input. The z-axis is determined by the choice of style.
72
73    For 'magnitude' it is the magnitude or norm of the output of f(s) = f(x+iy).
74
75    For 'real' it is the real part of the output of f(s) = f(x+iy).
76
77    For 'imaginary' it is the imaginary part of the output of f(s) = f(x+iy).
78
79    For 'argument' or 'phase' it is the argument/phase of the output of f(s) = f(x+iy).
80    (In other words, if you think of the complex number in polar coordinates, it is the
81    theta of the output, in the sense of x+iy = rho*(cos(theta) + i*sin(theta)). The
82    rho is the magnitude.
83    """
84    g(x,y) = f( x + i*y )
85
86    if ( (style=='magnitude') or (style=='Magnitude') or (style=='MAGNITUDE') ):
87        real_g(x,y) = real_part( g(x,y) )
88        imag_g(x,y) = imag_part( g(x,y) )
89        answer(x,y) = sqrt( real_g(x,y)^2 + imag_g(x,y)^2 )
90        #  answer(x,y) = real_part( sqrt( real_g(x,y)^2 + imag_g(x,y)^2 ) )     considered and rejected, Dec 26th, 2016
91    elif ( (style=='real') or (style=='Real') or (style=='REAL') ):
92        answer(x,y) = real_part( g(x,y) )
93    elif ( (style=='imaginary') or (style=='Imaginary') or (style=='IMAGINARY')
94           or (style=='imag') or (style=='Imag') or (style=='IMAG')):
95        answer(x,y) = imag_part( g(x,y) )
96    elif ( (style=='argument') or (style=='Argument') or (style=='ARGUMENT')
97           or (style=='phase') or (style=='Phase') or (style=='PHASE')):
98        return newComplexArgumentPlot3d( f, xmin, xmax, ymin, ymax, zmin, zmax, **kwargs )
99    elif ( (style=='mixed') or (style=='Mixed') or (style=='MIXED')):
100        real_g(x,y) = real_part( g(x,y) )
101        imag_g(x,y) = imag_part( g(x,y) )
102        answer(x,y) = sqrt( real_g(x,y)^2 + imag_g(x,y)^2 )
103        T = lambda x,y,z : ( CC( g(x=x,y=y) ).argument() + N(pi) ) / (2*N(pi))
104
105        new_color_option = (T, colormaps.gist_rainbow)
106
107        kwargs['color'] = new_color_option
108        kwargs['viewer'] = 'tachyon'
109
110        return new_plot3d( answer(x,y), xmin, xmax, ymin, ymax, zmin, zmax, **kwargs )
111    else:
112        assert false, "I have no idea what you are asking me for."
113
114    P = new_plot3d( answer(x,y), xmin, xmax, ymin, ymax, zmin, zmax, **kwargs )
115
116    return P
117
118
119