Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding text on a plot #422

Open
maclariz opened this issue Jan 31, 2023 · 8 comments
Open

Adding text on a plot #422

maclariz opened this issue Jan 31, 2023 · 8 comments
Labels
documentation-examples Consider making into a documentation example enhancement New feature or request

Comments

@maclariz
Copy link

maclariz commented Jan 31, 2023

I cannot seem to add text within a stereographic plot. Here is the code:

axh = plt.subplot(gs[2,2:4], projection='stereographic')
axh.scatter(v_alpha2_pruned, ec='k', linewidths=0.5, c=labels_rgb_pruned, 
                     alpha=0.7, s=120, marker='o')
axh.text(Vector3d.from_polar(1,1),letter[7], size=20)

The errors said the position had to be defined as a Vector3d. I did this, and still it fails:

TypeError                                 Traceback (most recent call last)
Input In [200], in <cell line: 56>()
     53 axh = plt.subplot(gs[2,2:4], projection='stereographic')
     54 axh.scatter(v_alpha2_pruned, ec='k', linewidths=0.5, c=labels_rgb_pruned, 
     55                      alpha=0.7, s=120, marker='o')
---> 56 axh.text(Vector3d.from_polar(1,1),letter[7], size=20)
     58 axi = plt.subplot(gs[2,4:6], projection='plot_map')
     59 axi.plot_map(Timap["Alpha Titanium"], labels_rgb, scalebar_properties={"location": 4})

File /local/environments/kernel/kernel-venv/lib64/python3.8/site-packages/orix/plot/stereographic_plot.py:238, in StereographicPlot.text(self, *args, **kwargs)
    219 """Add text to the axes.
    220 
    221 This method overwrites :meth:`matplotlib.axes.Axes.text`, see
   (...)
    235 matplotlib.axes.Axes.text
    236 """
    237 new_kwargs = dict(va="bottom", ha="center", zorder=ZORDER["text"])
--> 238 out = self._prepare_to_call_inherited_method(args, kwargs, new_kwargs)
    239 x, y, _, updated_kwargs = out
    240 if x.size == 0:

File /local/environments/kernel/kernel-venv/lib64/python3.8/site-packages/orix/plot/stereographic_plot.py:757, in StereographicPlot._prepare_to_call_inherited_method(self, args, kwargs, new_kwargs, sort)
    755     for k, v in new_kwargs.items():
    756         updated_kwargs.setdefault(k, v)
--> 757 x, y, visible = self._pretransform_input(args, sort=sort)
    758 return x, y, visible, updated_kwargs

File /local/environments/kernel/kernel-venv/lib64/python3.8/site-packages/orix/plot/stereographic_plot.py:792, in StereographicPlot._pretransform_input(self, values, sort)
    790         azimuth = azimuth[order]
    791         polar = polar[order]
--> 792     x, y = self._projection.spherical2xy(azimuth=azimuth, polar=polar)
    793     v = self._inverse_projection.xy2vector(x, y)
    794 else:

File /local/environments/kernel/kernel-venv/lib64/python3.8/site-packages/orix/projections/stereographic.py:117, in StereographicProjection.spherical2xy(self, azimuth, polar)
     85 def spherical2xy(
     86     self, azimuth: Union[float, np.ndarray], polar: Union[float, np.ndarray]
     87 ) -> Tuple[np.ndarray, np.ndarray]:
     88     r"""Return stereographic coordinates (X, Y) from 3D unit vectors
     89     created from spherical coordinates, azimuth :math:`\phi` and
     90     polar :math:`\theta`, defined as in the ISO 31-11 standard
   (...)
    115     vector2xy
    116     """
--> 117     v = Vector3d.from_polar(azimuth=azimuth, polar=polar)
    118     return self.vector2xy(v)

File /local/environments/kernel/kernel-venv/lib64/python3.8/site-packages/orix/vector/vector3d.py:431, in Vector3d.from_polar(cls, azimuth, polar, radial)
    429 azimuth = np.atleast_1d(azimuth)
    430 polar = np.atleast_1d(polar)
--> 431 sin_polar = np.sin(polar)
    432 x = np.cos(azimuth) * sin_polar
    433 y = np.sin(azimuth) * sin_polar

TypeError: ufunc 'sin' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
@hakonanes
Copy link
Member

axh.text(Vector3d.from_polar(1,1),letter[7], size=20)

What is letter[7] here? I think you have to specify it as a keyword argument s=letter[7].

@hakonanes
Copy link
Member

I must say not being able to pass cartesian (x, y) to StereographicPlot.text() has annoyed me sometimes. One solution is to "bypass" our custom text() method (docs) when x and y are among the keyword arguments, and use Matplotlib directly to place a piece of text. I think this is clean and straight forward.

@maclariz
Copy link
Author

Okay, your workaround works, you do not normally need to tell "text" that a text string is the text. i.e. this code worked in all other cells that weren't stereographic...
It not being cartesian and not being allowed to specify transform=axh.transAxes is annoying but easy to work around

@hakonanes
Copy link
Member

you do not normally need to tell "text" that a text string is the text. i.e. this code worked in all other cells that weren't stereographic...

You are right, with the StereographicPlot we have overwritten Axes.plot(), scatter() and text() to allow passing a Vector3d or azimuthal and polar angles (see e.g. the scatter() docs). To separate between these two types of input, our overridden methods require all other arguments passed on to Matplotlib to be keyword arguments. This is stated in the docstrings. I don't see a way to have this functionality and still allow a string to be the second argument (not keyword argument) passed.

@maclariz
Copy link
Author

It's fine. Just confusing first time.

@hakonanes hakonanes added the enhancement New feature or request label Jan 31, 2023
@hakonanes
Copy link
Member

I suggest to leave this open until we've either implemented my suggestion in #422 (comment) or have decided it's not a good idea.

Thank you for opening this issue, @maclariz.

@hakonanes hakonanes added the documentation-examples Consider making into a documentation example label Feb 2, 2023
@maclariz
Copy link
Author

maclariz commented Feb 2, 2023

I will also comment that you did not touch ax.set_title, so this can still be used. For what I was doing (adding letters a)-h) for a multipart figure), this was fine, as I only needed something in top left, so could use:

ax.set_title(letter[i], loc='left')

@hakonanes
Copy link
Member

Just realized we haven't overwritten Figure.text(). We can use this method to add text as normal with Matplotlib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation-examples Consider making into a documentation example enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants