You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I managed to create this plot using the following code:
fromitertoolsimportcountfrommathimportcopysign# https://pypi.org/project/prefixed/fromprefixedimportFloatfrommatplotlib.tickerimportScalarFormatterclassFrequencyFormatter(ScalarFormatter):
defformat_data(self, value):
# Add the Hz suffixreturn'{:H}Hz'.format(Float(value))
def_set_order_of_magnitude(self):
super()._set_order_of_magnitude()
c=abs(self.orderOfMagnitude)
# Search 0, -3, 3, -6, 6, -9, 9 etc until the best scientifically# prefixed oom is found, and then set self.orderOfMagnitude to itforsciOomincount(3,3):
ifc<sciOom:
self.orderOfMagnitude=copysign(sciOom, self.orderOfMagnitude)
break# fig,ax...ax.yaxis.set_major_formatter(FrequencyFormatter(
# I'm not necessarily interested in this, but without this,# ScalarFormatter.get_offset doesn't use my own .format_data function to# format also the offset.useMathText=True
))
It is not ideal because it relies both upon modifying (the private) _set_order_of_magnitude method and the external library prefixed, which implements something already implemented in the EngFormatter.
I'm surprised that EngFormatter doesn't handle offsets so smartly like ScalarFormatter...
Where do you think this kind of enhancement would fit most? In EngFormatter with an additional __init__ argument? Or in a new formatter?
Yea sure, I was thinking about that the same, EngFormatter already includes most of the functionality of prefixed.Float, it's just that it wasn't accessible to me when I inherited functionality from ScalarFormatter, and I wanted a quick solution.
I think mirroring the ScalarFormatter offset functionality to EngFormatter is a reasonable thing to do.
OK I agree with that, in terms of the UX/UI of the library, I'd imagine this kind of usage:
ax.yaxis.set_major_formatter(EngFormatter(
# Perhaps this should be the default value?useOffset=True
))
The dilemma I'm facing though when I'm thinking of implementing this feature, is the fact that most of the code that computes constantly the data's orderOfMagnitude and the offset, is located now in "private" methods of ScalarFormatter, and EngFormatter's parent class is Formatter which doesn't include that functionality.
Hence I'm not sure in to which class to put the functions that compute the order of magnitude and the offset. Perhaps I should make EngFormatter a child class of ScalarFormatter? what do you think?
Rather than go down the complexity of OO inheritance choices, I suggest we pull the re-usable code out into def _top_level_function(...): ... in the module and have each of the classes call them (passing in what ever state they need to pass in).
It was pretty hard to implement this without subclassing ScalarFormatter, because the decision what offset to use is heavily reliant upon many variables which I don't want to pass to external static functions. I hope you'll like the implementation at #28495 .
Activity
tacaswell commentedon Jun 26, 2024
I think mirroring the
ScalarFormatteroffset functionality toEngFormatteris a reasonable thing to do.I am pretty 👎🏻 on picking up a dependency though.
doronbehar commentedon Jun 26, 2024
Yea sure, I was thinking about that the same,
EngFormatteralready includes most of the functionality ofprefixed.Float, it's just that it wasn't accessible to me when I inherited functionality fromScalarFormatter, and I wanted a quick solution.OK I agree with that, in terms of the UX/UI of the library, I'd imagine this kind of usage:
The dilemma I'm facing though when I'm thinking of implementing this feature, is the fact that most of the code that computes constantly the data's
orderOfMagnitudeand the offset, is located now in "private" methods ofScalarFormatter, andEngFormatter's parent class isFormatterwhich doesn't include that functionality.Hence I'm not sure in to which class to put the functions that compute the order of magnitude and the offset. Perhaps I should make
EngFormattera child class ofScalarFormatter? what do you think?tacaswell commentedon Jun 27, 2024
Rather than go down the complexity of OO inheritance choices, I suggest we pull the re-usable code out into
def _top_level_function(...): ...in the module and have each of the classes call them (passing in what ever state they need to pass in).ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
doronbehar commentedon Jul 1, 2024
It was pretty hard to implement this without subclassing
ScalarFormatter, because the decision what offset to use is heavily reliant upon many variables which I don't want to pass to external static functions. I hope you'll like the implementation at #28495 .ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
13 remaining items
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: base upon ScalarFormatter
ticker.EngFormatter: allow offset (#28495)
QuLogic commentedon Mar 19, 2026
This was implemented in #28495.