#!/usr/bin/env python # coding: utf-8 # # Region visualisation # # It is sometimes useful to visualise the region we defined, either to make sure it is what we thought or to use it in more complex plots. In this tutorial, we show some basic as well as some more advanced ways of customising our plots. # # We are going to use the same region we used in the previous tutorial: # # $$p_{1} = (0, 0, 0)$$ # $$p_{2} = (l_{x}, l_{y}, l_{z})$$ # In[1]: import discretisedfield as df # df is here chosen to be an alias for discretisedfield p1 = (0, 0, 0) p2 = (100e-9, 50e-9, 20e-9) region = df.Region(p1=p1, p2=p2) # There are two main ways how we can visualise objects in `discretisedfield`: # # 1. Using `matplotlib` (static 2D plots, usually with some tricks to make them look 3D) # 2. Using `pyvista` (interactive 3D plots) # # All `matplotlib` method names start with `mpl`, whereas all `pyvista` plots start with `pyvista`. We will first have a look at simple plotting using both `matplotlib` and `pyvista` and later look at how we can pass different parameters to change them. # # ## Basic plotting # # To get a quick `matploltlib` "3D" plot of the region, we call `mpl`: # In[2]: region.mpl() # Without passing any parameters to `mpl` function, some default settings are chosen. We can see that `matplotlib` is not good in showing the right proportions of the region. More precisely, we know that the region is much thinner in the z-direction, but that is not the impression we get from the plot. This is the main disadvatage of `mpl`. # # Now, we can ask our region object for an interactive `pyvista` plot: # In[3]: region.pyvista() # This is now an interactive plot, which we can zoom, rotate, etc. In addition, a small contol panel is shown in the top-left corner, where we can modify some of the plot's properties. The region is now shown in right proportions. # ## Advanced plotting # # Here we explore what parameters we can pass to `mpl` and `pyvista` functions. Let us start with `mpl`. # # ### `mpl` # # The default plot is: # In[4]: region.mpl() # If we want to change the figure size, we can pass `figsize` parameter. Its value must be a lenth-2 tuple, with the first element being the size in the horizontal direction, whereas the second element is the size in the vertical direction. # In[5]: region.mpl(figsize=(10, 5)) # The color of the lines depicting the region we can choose by passing `color` argument. `color` must be a valid `matplotlib` color. For instance, it can be an RGB hex-string ([online converter](http://www.javascripter.net/faq/rgbtohex.htm)). # In[6]: region.mpl(color="#9400D3") # `discretisedfield` automatically chooses the SI prefix (nano, micro, etc.) it is going to use to divide the axes with and show those units on the axes. Sometimes (e.g. for thin films), `discretisedfield` does not choose the SI prefix we expected. In those cases, we can explicitly pass it using `multiplier` argument. ``multiplier`` can be passed as $10^{n}$, where $n$ is a multiple of 3 (..., -6, -3, 0, 3, 6,...). For instance, if `multiplier=1e-6` is passed, all axes will be divided by $1\,\mu\text{m}$ and $\mu\text{m}$ units will be used as axis labels. # In[7]: region.mpl(multiplier=1e-6) # If we want to save the plot, we pass `filename` and region object is going to show and save the plot in our working directory as a PDF. # In[8]: region.mpl(filename="my-region-plot.pdf") # `mpl` region plot is based on [`matplotlib.pyplot.plot` function](https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.plot.html). Therefore, any parameter accepted by it can be passed. For instance: # In[9]: region.mpl(marker="o", linestyle="dashed") # Finally, we show how to expose the axes on which the region is plotted, so that we can customise them. We do that by creating the axes ourselves and then passing them to `mpl` function. # In[10]: import matplotlib.pyplot as plt # Create the axes fig = plt.figure(figsize=(8, 5)) ax = fig.add_subplot(111, projection="3d") # Add the region to the axes region.mpl(ax=ax) # Customise the axes ax.set_xlabel("length") ax.set_ylabel("width") ax.set_zlabel("height") # This way, by exposing the axes and passing any allowed `matplotlib.pyplot.plot` argument, we can customise the plot any way we like (as long as it is allowed by `matplotlib`). # # ### `pyvista` # # Default `pyvista`` plot is: # In[11]: region.pyvista() # If we want to change the color, we can pass `color` argument. It has to be an `int`. # In[12]: region.pyvista(color="FF5733") # Similar to the `mpl` plot, we can change the axes multiplier. # In[13]: region.pyvista(multiplier=1e-6) # `pyvista` plot is based on [pyvista](https://docs.pyvista.org/version/stable/), so any parameter accepted by it can be passed. For instance: # In[14]: region.pyvista(opacity=0.5) # We can also expose `pyvista.Plotter` object and customise it. # In[15]: import pyvista as pv # Expose plot object plotter = pv.Plotter() # Add region to the plot region.pyvista(plotter=plotter) # Modify the plotter - in this case we add a ruler plotter.add_ruler(pointa=(0, 0, 20), pointb=(100, 50, 20)) # Display the plot plotter.show() # This way, we can modify the plot however we want (as long as `pyvista` allows it).