<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Plot VTK files using Matplotlib
This library is useful to plot vector fields stored in VTK files (e.g. vtu or vtk) using Matplotlib
Libraries
Step1:  Generate 2D Vector Field using Dolfin
We will generate a random two dimensional vector field using Fenics (Dolfin) in a 3x3 square mesh
Step2:  Now we can save the data in a VTK file. By default, Fenics saves XML files (instead of binary) using an unstructured grid, with the .vtu extension
Step3:  Consequently, we initialise the plotting library passing the path to the VTK file. When loading the data, we must specify the range of spatial z values from where a slice of data is going to be plotted.
After starting the plot_vtk_matplotlib class with the VTK file path, it is necessary to extract the data. The vtkXMLUnstructuredGrid is the default format option to load the data from the .vtu file. We can change this option using the vtkfiletype argument (see the documentation for more details).
Step4:  We now start exprimenting with the options. One of the most interesting functions is plot_vtk which shows an interpolated colormap using the data in the slice specified when extracting the information.
One of the nicest features of this function is to use a HSV mapping to show the orientation of the in plane components of the vectors, which can be mapped in the range 0 to 2 $\pi$.
By default, the quiver plot on top is shown with the raw data and a inverted colormap (if not HSV) or as black arrows if using the HSV option. The arrows color can be modified playing with the quiver_type options, which can also specify if the vector field arrows are going to be interpolated in a regular grid using the data from the slice. The HSV mapping uses SciPy.
In this case we use the the '2d' option for the hsv_map option since we have a 2D vector field. The VTK file in this case has the z components set as zero and if using '3d' the background would look black.
The arrows in the quiver plot are drawn at the center of the grid nodes (in Matplotlib their are drawn from the tail, as default). This option can be changed using the pivot option.
The colormap is interpolated in an nx by ny grid.
Step5:  The default option is to use a colormap for the interpolated data. We can also specify to use natgrid instead of scipy for interpolating the data. The linear method is better than the default 'nn' (natural neighbours) but still a bad approximation, compared with SciPy.
Step6:  We can also use a quiver plot, which can also be interpolated if necessary. Extra arguments can be passed to control the arrow definitions. The default interpolation is made with SciPy and a linear method. These options can be changed with interpolator and interpolator_method respectively.
Step7:  3D Vector Field
We will now generate a 3D vector field inside a sphere to test how the slicing works
Step8:  We save the data as before
Step9:  Now we load the function and specify a slice in the middle of the sphere
Step10:  If we plot the slice with a 3D HSV mapping, darker regions indicate the lower $z$ magnitudes of the vector field, while the brighter regions indicate the highest $z$ values.
Step11:  We can interpolate this slice and get a quiver plot from the vector field
Step12:  We can also redefine the range of $z$ values where the data is extracted, but this is not very accurate for a mesh in finite elements since many points are not exactly in the slice plane, thus the approximation can be bad. The quiver plot on top can be disabled making the quiver_type as None or False.
Step13:  Extending with Matplotlib
We can use predefined axes to generate, for instance, grids of plots. We will use the vf_plot object from the previous section
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
# To generate the vector fields
import dolfin as df
import mshr
import numpy as np
import plot_vtk_matplotlib as pvm
# Matplotlib parameters can be tuned with rc.Params
# This library has modified values. For example:
# matplotlib.rcParams['font.size'] = 22
Explanation: Plot VTK files using Matplotlib
This library is useful to plot vector fields stored in VTK files (e.g. vtu or vtk) using Matplotlib
Libraries
End of explanation
mesh = mshr.Rectangle(df.Point(-3, -3), df.Point(3, 3))
mesh = mshr.generate_mesh(mesh, 10)
vspace = df.VectorFunctionSpace(mesh, 'Lagrange', degree=1, dim=2)
vfunction = df.Expression(("sin(x[1])", "cos(x[0])"))
vfunction = df.interpolate(vfunction, vspace)
# df.plot(vfunction, interactive=True)
Explanation: Generate 2D Vector Field using Dolfin
We will generate a random two dimensional vector field using Fenics (Dolfin) in a 3x3 square mesh
End of explanation
_file = df.File('dolfin_vector_field_2d.pvd')
_file << vfunction
Explanation: Now we can save the data in a VTK file. By default, Fenics saves XML files (instead of binary) using an unstructured grid, with the .vtu extension
End of explanation
# Load our skyrmionic state
vf_plot = pvm.plot_vtk_matplotlib('./dolfin_vector_field_2d000000.vtu',
                                  z_max=1, z_min=-1,
                                  )
# Extract the data from the file
vf_plot.extract_data(# vtkfiletype=XMLStructuredGrid
                     )
Explanation: Consequently, we initialise the plotting library passing the path to the VTK file. When loading the data, we must specify the range of spatial z values from where a slice of data is going to be plotted.
After starting the plot_vtk_matplotlib class with the VTK file path, it is necessary to extract the data. The vtkXMLUnstructuredGrid is the default format option to load the data from the .vtu file. We can change this option using the vtkfiletype argument (see the documentation for more details).
End of explanation
# Plot the y component and arrows in black
vf_plot.plot_vtk(-3, 3,
                -3, 3,
                # nx=50, ny=50,
                v_component='vy',
                hsv_map='2d',
                # figsize=(10, 10),
                # savefig='hsv_map.pdf',
                colorbar=True,
                quiver_type='raw_colour',
                )
Explanation: We now start exprimenting with the options. One of the most interesting functions is plot_vtk which shows an interpolated colormap using the data in the slice specified when extracting the information.
One of the nicest features of this function is to use a HSV mapping to show the orientation of the in plane components of the vectors, which can be mapped in the range 0 to 2 $\pi$.
By default, the quiver plot on top is shown with the raw data and a inverted colormap (if not HSV) or as black arrows if using the HSV option. The arrows color can be modified playing with the quiver_type options, which can also specify if the vector field arrows are going to be interpolated in a regular grid using the data from the slice. The HSV mapping uses SciPy.
In this case we use the the '2d' option for the hsv_map option since we have a 2D vector field. The VTK file in this case has the z components set as zero and if using '3d' the background would look black.
The arrows in the quiver plot are drawn at the center of the grid nodes (in Matplotlib their are drawn from the tail, as default). This option can be changed using the pivot option.
The colormap is interpolated in an nx by ny grid.
End of explanation
# Plot the y component and arrows in black
vf_plot.plot_vtk(-3, 3,
                -3, 3,
                nx=50, ny=50,
                v_component='vx', 
                # cmap='RdBu',
                interpolator='natgrid',
                interpolator_method='linear', 
                # figsize=(10, 10),
                colorbar=True,
                # quiver_type='raw_colour',
                )
Explanation: The default option is to use a colormap for the interpolated data. We can also specify to use natgrid instead of scipy for interpolating the data. The linear method is better than the default 'nn' (natural neighbours) but still a bad approximation, compared with SciPy.
End of explanation
# Quiver plot
vf_plot.plot_quiver(quiver_type='interpolated_cmap',
                    x_min=-3, x_max=3,
                    y_min=-3, y_max=3,
                    linewidth=0.8, 
                    scale=1 / 0.06,
                    width=0.007,
                    alpha=0.8,
                    v_component='vx',
                    # pivot='tail'
                    # savefig='vector_field.png'
                    )
Explanation: We can also use a quiver plot, which can also be interpolated if necessary. Extra arguments can be passed to control the arrow definitions. The default interpolation is made with SciPy and a linear method. These options can be changed with interpolator and interpolator_method respectively.
End of explanation
mesh = mshr.Sphere(df.Point(0, 0), 5)
mesh = mshr.generate_mesh(mesh, 10)
vspace = df.VectorFunctionSpace(mesh, 'Lagrange', degree=1, dim=3)
vfunction = df.Expression(("sin(x[1])", "cos(x[0])", "sin(x[2])"))
vfunction = df.interpolate(vfunction, vspace)
# We can plot the field using Dolfin 
# df.plot(vfunction, interactive=True)
# We can plot the mesh
# df.plot(mesh, interactive=True)
Explanation: 3D Vector Field
We will now generate a 3D vector field inside a sphere to test how the slicing works:
End of explanation
_file = df.File('dolfin_sphere_vector_field_3d.pvd')
_file << vfunction
Explanation: We save the data as before:
End of explanation
# Load our skyrmionic state
vf_plot = pvm.plot_vtk_matplotlib('./dolfin_sphere_vector_field_3d000000.vtu',
                                  z_max=0.8, z_min=-0.8)
# Extract the data from the file
vf_plot.extract_data()
Explanation: Now we load the function and specify a slice in the middle of the sphere
End of explanation
# plot the x component and arrows in black
vf_plot.plot_vtk(-5, 5,
                -5, 5,
                nx=100, ny=100,
                v_component='vz',
                hsv_map='3d',
                # figsize=(10, 8),
                colorbar=True,
                quiver_type='raw_colour', 
                )
Explanation: If we plot the slice with a 3D HSV mapping, darker regions indicate the lower $z$ magnitudes of the vector field, while the brighter regions indicate the highest $z$ values.
End of explanation
# Quiver plot
vf_plot.plot_quiver(quiver_type='interpolated_cmap',
                    x_min=-5, x_max=5,
                    y_min=-5, y_max=5,
                    linewidth=0.8, 
                    scale=1 / 0.06,
                    width=0.007,
                    alpha=0.8,
                    v_component='vz'
                    )
Explanation: We can interpolate this slice and get a quiver plot from the vector field
End of explanation
vf_plot.z_min, vf_plot.z_max = 4, 5
# Quiver plot
vf_plot.plot_vtk(-5, 5,
                -5, 5,
                nx=100, ny=100,
                v_component='vy',
                hsv_map='2d',
                colorbar=True,
                quiver_type=None,
                )
Explanation: We can also redefine the range of $z$ values where the data is extracted, but this is not very accurate for a mesh in finite elements since many points are not exactly in the slice plane, thus the approximation can be bad. The quiver plot on top can be disabled making the quiver_type as None or False.
End of explanation
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(18, 6))
comps = ['vx', 'vy', 'vz']
for i in range(3):
    ax = fig.add_subplot(1, 3, i + 1)
    
    vf_plot.plot_quiver(quiver_type='interpolated_cmap',
                    x_min=-5, x_max=5,
                    y_min=-5, y_max=5,
                    linewidth=0.8, 
                    scale=1 / 0.06,
                    width=0.007,
                    alpha=0.8,
                    cmap='RdYlBu',
                    v_component=comps[i],
                    predefined_axis=ax,
                    )
    ax.set_title(comps[i])
    # ax.axis('off')
Explanation: Extending with Matplotlib
We can use predefined axes to generate, for instance, grids of plots. We will use the vf_plot object from the previous section
End of explanation
<END_TASK>