-
Notifications
You must be signed in to change notification settings - Fork 466
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
plotting with pint quantities #317
Comments
OK so there is some foundation over at matplotlib: https://matplotlib.org/api/units_api.html#module-matplotlib.units Can anyone speak to whether pint is compatible or how hard it would be to make it compatible? |
We will be very happy to provide something like this. As far as I know, nobody has tried it but should be doable. We will be happy to help you out if you need it. |
I've been playing off and on with using pint with matplotlib--version 1.5 of matplotlib has some crucial fixes for using pint with the units support. Here's the code I've used to enable the registration, but I haven't played around enough to know if it's a solid, complete implementation: import matplotlib.units as munits
# Implementation of matplotlib support for unit conversion using pint
class PintConverter(munits.ConversionInterface):
@staticmethod
def convert(value, unit, axis):
return value.to(unit)
@staticmethod
def axisinfo(unit, axis):
return None
@staticmethod
def default_units(x, axis):
return x.to_base_units()
# Register the class
munits.registry[units.Quantity] = PintConverter() |
So it seems things work pretty well with matplotlib 2.0.2 (as well as its master branch). I've made this work pretty well so far: import matplotlib.units as munits
class PintAxisInfo(munits.AxisInfo):
"""Support default axis and tick labeling and default limits."""
def __init__(self, units):
"""Set the default label to the pretty-print of the unit."""
super(PintAxisInfo, self).__init__(label='{:P}'.format(units))
class PintConverter(munits.ConversionInterface):
"""Implement support for pint within matplotlib's unit conversion framework."""
@staticmethod
def convert(value, unit, axis):
"""Convert pint :`Quantity` instances for matplotlib to use."""
if isinstance(value, (tuple, list)):
return [PintConverter._convert_value(v, unit, axis) for v in value]
else:
return PintConverter._convert_value(value, unit, axis)
@staticmethod
def _convert_value(value, unit, axis):
"""Handle converting using attached unit or falling back to axis units."""
if hasattr(value, 'units'):
return value.to(unit).magnitude
else:
return units.Quantity(value, axis.get_units()).to(unit).magnitude
@staticmethod
def axisinfo(unit, axis):
"""Return axis information for this particular unit."""
return PintAxisInfo(unit)
@staticmethod
def default_units(x, axis):
"""Get the default unit to use for the given combination of unit and axis."""
return getattr(x, 'units', None)
# Register the class
munits.registry[units.Quantity] = PintConverter() @hgrecco Is there any interest in having this baked into pint itself? We could add a function for users to call that triggers the matplotlib import and registration of the unit handling for matplotlib. |
This would be awesome! Please do a PR and we can discuss it there. I think we need |
These are optionally enabled on the UnitRegistry.
549: Matplotlib support r=hgrecco a=dopplershift This adds a method to `UnitRegistry` that hooks up handlers for `Quantity` instances within matplotlib's unit machinery: ```python import pint ureg = pint.UnitRegistry() ureg.setup_matplotlib() ``` This support can also be disabled with: ```python ureg.setup_matplotlib(False) ``` Closes #317.
These are optionally enabled on the UnitRegistry.
I am interested in a combination between pint and matplotlib.
I imagine this would take a lot of work with the matplotlib package, but I thought I'd ask here as there might be more interest here. Has this been proposed or attempted? Does anyone else think this would be really cool?
The text was updated successfully, but these errors were encountered: