-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path_plot_poincare.py
81 lines (75 loc) · 2.99 KB
/
_plot_poincare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def plot_poincare(self, toroidalIdx=0, prange="full", ax=None, **kwargs):
"""Poincare plots
Args:
toroidalIdx (int, optional): The index of toroidal cross-section to be plotted. Defaults to 0.
prange (str, optional): Range of plotted points, one of ['full', 'upper', 'lower']. Defaults to 'full'.
ax (Matplotlib axis, optional): Matplotlib axis to be plotted on. Defaults to None.
kwargs (dict, optional): keyword arguments. Matplotlib.pyplot.scatter keyword arguments.
Raises:
ValueError: prange should be one of ['full', 'upper', 'lower']
Returns:
pyplot.scatter: Matplotlib.pyplot.scatter returns
"""
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import numpy as np
# extract slice corresponding to the given toroidal cutplane
Igeometry = self.input.physics.Igeometry
if Igeometry == 3:
rr = self.poincare.R[:, :, toroidalIdx]
zz = self.poincare.Z[:, :, toroidalIdx]
elif Igeometry == 1:
rr = np.mod(self.poincare.t[:, :, toroidalIdx], np.pi * 2)
zz = self.poincare.R[:, :, toroidalIdx]
elif Igeometry == 2:
rr = self.poincare.R[:, :, toroidalIdx] * np.cos(
self.poincare.t[:, :, toroidalIdx]
)
zz = self.poincare.R[:, :, toroidalIdx] * np.sin(
self.poincare.t[:, :, toroidalIdx]
)
# Replace invalid values (unsuccessful tracing) with nan for plotting
zz[(self.poincare.success[:,np.newaxis]!=1) | ((rr==0) & (zz==0))] = np.nan
rr[(self.poincare.success[:,np.newaxis]!=1) | ((rr==0) & (zz==0))] = np.nan
# get axix data
if ax is None:
fig, ax = plt.subplots()
plt.sca(ax)
# set default plotting parameters
# use dots
if "marker" not in kwargs:
kwargs.update({"marker": "."})
# use gray color
if "c" not in kwargs:
pass
# size of marker
if "s" not in kwargs:
kwargs.update({"s": 0.3})
# kwargs.update({"c": "gray"})
# make plot depending on the 'range'
if prange == "full":
nptrj = rr.shape[0]
for ii in range(nptrj):
dots = ax.scatter(rr[ii, :], zz[ii, :], **kwargs)
elif prange == "upper":
dots = ax.scatter(rr[zz >= 0], zz[zz >= 0], **kwargs)
elif prange == "lower":
dots = ax.scatter(rr[zz <= 0], zz[zz <= 0], **kwargs)
else:
raise ValueError("prange should be one of ['full'(default), 'upper', 'lower'].")
# adjust figure properties
if self.input.physics.Igeometry == 3:
plt.xlabel("R [m]", fontsize=20)
plt.ylabel("Z [m]", fontsize=20)
plt.axis("equal")
if self.input.physics.Igeometry == 2:
plt.xlabel("X [m]", fontsize=20)
plt.ylabel("Y [m]", fontsize=20)
plt.axis("equal")
if self.input.physics.Igeometry == 1:
plt.ylabel("R [m]", fontsize=20)
plt.xlabel(r"$\theta$", fontsize=20)
plt.xlim([0, 2*np.pi])
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
return ax