Replies: 4 comments
-
You raise good points regarding the limitations of Some questions and thoughts:
|
Beta Was this translation helpful? Give feedback.
-
Thanks for reading this and giving feedback, this was helpful. To preface my response, I am going to quote the MTEX page for Gridded EBSD Data because I think they hit the nail on the head:
(Omissions added for clarity, full quote at link) At this stage, I'm not claiming we should make the default To your points though @hakonanes :
It's rare my data isn't on a square or hex grid, but like the quote from MTEX implies, I often want to look at and work on irregular subsections. An easy example is pulling out a handful of grains from a map of 3,000 to do a Parent Reconstruction, local cleanup, plotting, etc. Being able to pull out just the spots of interest via indexing (as done in MTEX) is super handy. It also makes problems easy to parallelize on a per-grain basis.
This wasn't the best demonstration by me. I was alluding to the fact that with an ungridded Map approach, you can pull out just subsections of interest to look at as opposed to relying on masking, which saves time and memory
Neat! This is getting closer to what i actually want, but switching to a new method that cannot plot on day one seemed like a no-go, so I wanted to start with the plotting problem.
This is a good point. I think the in-between might be to allow plotting any patch, but default to a square and add other defaults down the road.
I'm sort of cooling down on that option, I think it might be prohibitively slow to set up in Python. Leaving it here though in case someone else considers a similar approach, or figures out a way to improve what I did. |
Beta Was this translation helpful? Give feedback.
-
You seem to have thought about the structuring of crystallographic data a fair bit. Perhaps you can enlighten me as to what is meant by MTEX "ignoring gridding" in their
Yes, the current implementation in
Quoting myself, I should qualify that I cannot lead such work at the moment, but I can assist! |
Beta Was this translation helpful? Give feedback.
-
I took the liberty of converting the issue to a discussion, since you have the word "discussion" in the title... |
Beta Was this translation helpful? Give feedback.
-
I've spent some time over the past few weeks working on this with limited success. Raising an issue here in hopes that some other people can weigh in with alternatives or advice.
Short version
orix.CrystalMap.plot
is fast but restrictive. A mesh representation would be more ideal, but at the cost of some speed. I tried several methods, of which I listed the three best below with example code:The issue:
orix.CrystalMap
currently plots EBSD images usingmatplotlib.pyplot.imshow
. This is fast and intuitive, but has some drawbacks:crystal_map.rotations
to be in the form of a correctly ordered 2d array.The General solution:
EBSD maps should instead be plotted using some type of mesh tool. This is what MTEX does. For example, run the following MATLAB code, and pause the code in "generateUnitCells.m" (github link here)
You can see that each "pixel" is really a copy of a polygon based on
ebsd.unitCell
with a transposed centroid. This has some important advantages:ebsd.prop.x
andebsd.prop.y
with the correct centroids.All that said, any mesh-based solution will inherently be slower than imshow. Thus, some considerable thought should be put into the best implementation.
Possible Implementation 1: Matplotlib
PatchCollection
This seems like the closest parallel to what MTEX already does. I tried several methods and various implementations of jit, numba, multithreading, GPU acceleration, etc, but it seems the fastest method is the one used on the backend of hexbins
PatchCollection
withoffsets=xy_centroids
Using dummy data, this looks a bit like this:
result looks like this, plots 2 million polygons in roughly 2-4 seconds (roughly comprable to MTEX)
The actual calculation is nearly instantaneous, it seems the holdup is in Matplotlib's plotting ability. Only real downside here is the plots are sluggish during zooming/panning, and adding tooltips will only slow this down further.
Possible Implementation 2: Plotting a triangle mesh using Matplotlib
tripcolor
Here is a good demo of tripcolor in action and here is a snippet of code I wrote using it on the same dataset as above
this seems to take much longer to calculate, but gives a more responsive plot. unfortunately, this ONLY works with TriMeshes (ie, meshes of triangles), which creates 2x as many faces for square grids and 6x for hex grids. This also means some additional book keeping has to be done.
There is also a quad mesh which seems to plot faster, but of course cannot do hexagonal plots. Also, these methods to not translate nicely to the concept of grain maps. (example of quad plot here)![https://matplotlib.org/stable/gallery/images_contours_and_fields/quadmesh_demo.html#sphx-glr-gallery-images-contours-and-fields-quadmesh-demo-py]
This FEELS like there should be a better way to make similar
pcolor
plots with irregular polygons, but I cannot figure it out. If someone else can, feel free to give it a go.Possible Implementation 3:
Plotly
For those who have not seen, you can do some incredibly cool interactive plots with plotly. In particular, an EBSD scan is essentially just what GIS people call a (Chloropleth, and plotly has some insanely fast tools for rendering them)[https://plotly.com/python/mapbox-county-choropleth/]
However, this has two downsides.
The first one seems acceptable, but the second one has been a problem. I can make super responsive 2000x2000 pixel ebsd plots and even 500x500x500 3d meshes, but writing them takes 5-10 minutes, because the python code is writing the data out as ASCII text. The fastest method I found was to build
Mesh3D
objects like this:Plots look like this. you get the tooltips for free, and can code in whatever information you want into them (rgb, euler angles, quaternion, axis-angle, etc)
Of course, this again brings up the problem of representing singular patches as multiple triangles.
I think there may be a more generic way to do this using
Plotly.go.Scatter
,where each pixel is a different Scatter object. However, this shouldn't be done in Python because it is prohibitively slow to write out the necessary JSON. THAT SAID, if someone knowledgeable in JS has interest, this seems like a much better plotting tool for what we want.Here is a very rough example for creating a50x50 grid.
If anyone has any input, issues, feedback, etc, let me know.
Beta Was this translation helpful? Give feedback.
All reactions