Skip to content

Commit dbd07df

Browse files
committed
WIP: animate function based on plot2d_polygon.
1 parent 64408ea commit dbd07df

File tree

1 file changed

+201
-1
lines changed

1 file changed

+201
-1
lines changed

xbout/plotting/animate.py

Lines changed: 201 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import matplotlib
33
import matplotlib.pyplot as plt
44
import warnings
5-
5+
from mpl_toolkits.axes_grid1 import make_axes_locatable
66
import animatplot as amp
77

88
from .utils import (
@@ -679,3 +679,203 @@ def animate_line(
679679
return anim
680680

681681
return line_block
682+
683+
def animate_polygon(
684+
da,
685+
ax=None,
686+
cax=None,
687+
cmap="viridis",
688+
norm=None,
689+
logscale=False,
690+
antialias=False,
691+
vmin=None,
692+
vmax=None,
693+
extend="neither",
694+
add_colorbar=True,
695+
colorbar_label=None,
696+
separatrix=True,
697+
separatrix_kwargs={"color": "white", "linestyle": "-", "linewidth": 2},
698+
targets=False,
699+
add_limiter_hatching=False,
700+
grid_only=False,
701+
linewidth=0,
702+
linecolor="black",
703+
):
704+
"""
705+
Nice looking 2D plots which have no visual artifacts around the X-point.
706+
707+
Parameters
708+
----------
709+
da : xarray.DataArray
710+
A 2D (x,y) DataArray of data to plot
711+
ax : Axes, optional
712+
Axes to plot on. If not provided, will make its own.
713+
cax : Axes, optional
714+
Axes to plot colorbar on. If not provided, will plot on the same axes as the plot.
715+
cmap : str or matplotlib.colors.Colormap, default "viridis"
716+
Colormap to use for the plot
717+
norm : matplotlib.colors.Normalize, optional
718+
Normalization to use for the color scale
719+
logscale : bool, default False
720+
If True, use a symlog color scale
721+
antialias : bool, default False
722+
Enables antialiasing. Note: this also shows mesh cell edges - it's unclear how to disable this.
723+
vmin : float, optional
724+
Minimum value for the color scale
725+
vmax : float, optional
726+
Maximum value for the color scale
727+
extend : str, optional, default "neither"
728+
Extend the colorbar. Options are "neither", "both", "min", "max"
729+
add_colorbar : bool, default True
730+
Enable colorbar in figure?
731+
colorbar_label : str, optional
732+
Label for the colorbar
733+
separatrix : bool, default True
734+
Add lines showing separatrices
735+
separatrix_kwargs : dict
736+
Keyword arguments to pass custom style to the separatrices plot
737+
targets : bool, default True
738+
Draw solid lines at the target surfaces
739+
add_limiter_hatching : bool, default True
740+
Draw hatched areas at the targets
741+
grid_only : bool, default False
742+
Only plot the grid, not the data. This sets all the polygons to have a white face.
743+
linewidth : float, default 0
744+
Width of the gridlines on cell edges
745+
linecolor : str, default "black"
746+
Color of the gridlines on cell edges
747+
"""
748+
749+
if ax is None:
750+
fig, ax = plt.subplots(figsize=(3, 6), dpi=120)
751+
else:
752+
fig = ax.get_figure()
753+
754+
if cax is None:
755+
cax = ax
756+
757+
if vmin is None:
758+
vmin = np.nanmin(da.values)
759+
760+
if vmax is None:
761+
vmax = np.nanmax(da.max().values)
762+
763+
if colorbar_label is None:
764+
if "short_name" in da.attrs:
765+
colorbar_label = da.attrs["short_name"]
766+
elif da.name is not None:
767+
colorbar_label = da.name
768+
else:
769+
colorbar_label = ""
770+
771+
if "units" in da.attrs:
772+
colorbar_label += f" [{da.attrs['units']}]"
773+
774+
if "Rxy_lower_right_corners" in da.coords:
775+
r_nodes = [
776+
"R",
777+
"Rxy_lower_left_corners",
778+
"Rxy_lower_right_corners",
779+
"Rxy_upper_left_corners",
780+
"Rxy_upper_right_corners",
781+
]
782+
z_nodes = [
783+
"Z",
784+
"Zxy_lower_left_corners",
785+
"Zxy_lower_right_corners",
786+
"Zxy_upper_left_corners",
787+
"Zxy_upper_right_corners",
788+
]
789+
cell_r = np.concatenate(
790+
[np.expand_dims(da[x], axis=2) for x in r_nodes], axis=2
791+
)
792+
cell_z = np.concatenate(
793+
[np.expand_dims(da[x], axis=2) for x in z_nodes], axis=2
794+
)
795+
else:
796+
raise Exception("Cell corners not present in mesh, cannot do polygon plot")
797+
798+
Nx = len(cell_r)
799+
Ny = len(cell_r[0])
800+
patches = []
801+
802+
# https://matplotlib.org/2.0.2/examples/api/patch_collection.html
803+
804+
idx = [np.array([1, 2, 4, 3, 1])]
805+
patches = []
806+
for i in range(Nx):
807+
for j in range(Ny):
808+
p = matplotlib.patches.Polygon(
809+
np.concatenate((cell_r[i][j][tuple(idx)], cell_z[i][j][tuple(idx)]))
810+
.reshape(2, 5)
811+
.T,
812+
fill=False,
813+
closed=True,
814+
facecolor=None,
815+
)
816+
patches.append(p)
817+
818+
norm = _create_norm(logscale, norm, vmin, vmax)
819+
820+
if grid_only is True:
821+
cmap = matplotlib.colors.ListedColormap(["white"])
822+
polys = matplotlib.collections.PatchCollection(
823+
patches,
824+
alpha=1,
825+
norm=norm,
826+
cmap=cmap,
827+
antialiaseds=antialias,
828+
edgecolors=linecolor,
829+
linewidths=linewidth,
830+
joinstyle="bevel",
831+
)
832+
833+
colors = da.data[0,:,:].flatten()
834+
polys.set_array(colors)
835+
ax.add_collection(polys)
836+
837+
#def update(frame):
838+
# # for each frame, update the data stored on each artist.
839+
# colors = da.data[frame,:,:].flatten()
840+
# polys.set_array(colors)
841+
# return polys
842+
def update(frame):
843+
colors = da.data[frame,:,:].flatten()
844+
polys.set_array(colors)
845+
print(da.data[0,0,0].compute())
846+
print(frame)
847+
#update(0)
848+
849+
if add_colorbar:
850+
# This produces a "foolproof" colorbar which
851+
# is always the height of the plot
852+
# From https://joseph-long.com/writing/colorbars/
853+
divider = make_axes_locatable(ax)
854+
cax = divider.append_axes("right", size="5%", pad=0.05)
855+
fig.colorbar(polys, cax=cax, label=colorbar_label, extend=extend)
856+
cax.grid(which="both", visible=False)
857+
858+
859+
860+
ax.set_aspect("equal", adjustable="box")
861+
ax.set_xlabel("R [m]")
862+
ax.set_ylabel("Z [m]")
863+
ax.set_ylim(cell_z.min(), cell_z.max())
864+
ax.set_xlim(cell_r.min(), cell_r.max())
865+
ax.set_title(da.name)
866+
867+
if separatrix:
868+
plot_separatrices(da, ax, x="R", y="Z", **separatrix_kwargs)
869+
870+
if targets:
871+
plot_targets(da, ax, x="R", y="Z", hatching=add_limiter_hatching)
872+
873+
#print(np.shape(da.data))
874+
#colors = da.data[0,:,:].flatten()
875+
#polys.set_array(colors)
876+
#ax.add_collection(polys)
877+
878+
879+
ani = matplotlib.animation.FuncAnimation(fig=fig, func=update, frames=np.shape(da.data)[0], interval=3000)
880+
return ani
881+

0 commit comments

Comments
 (0)