Plotting with scientific axis, changing the number of significant figures

不问归期 提交于 2021-02-15 03:51:15

问题


I am making the following plot in matplotlib, using amongst other things plt.ticklabel_format(axis='y',style='sci',scilimits=(0,3)). This yields a y-axis as so:

Now the problem is that I want the y-axis to have ticks from [0, -2, -4, -6, -8, -12]. I have played around with the scilimits but to no avail.

How can one force the ticks to only have one significant figure and no trailing zeros, and be floats when required?

MWE added below:

import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0.0, 10000.0, 10.)
s = np.sin(np.pi*t)*np.exp(-t*0.0001)

fig, ax = plt.subplots()

ax.tick_params(axis='both', which='major')
plt.ticklabel_format(style='sci', axis='x', scilimits=(0,3))
plt.plot(t,s)

plt.show()

回答1:


When I ran into this problem, the best I could come up with was to use a custom FuncFormatter for the ticks. However, I found no way to make it display the scale (e.g. 1e5) along with the axis. The easy solution was to manually include it with the tick label.

Sorry if this does not fully answer the question, but it may suffice as a relatively simple solution to the problem :)

In the MWE my solution looks somewhat like this:

import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import numpy as np


def tickformat(x):
    if int(x) == float(x):
        return str(int(x))
    else:
        return str(x)        


t = np.arange(0.0, 10000.0, 10.)
s = np.sin(np.pi*t)*np.exp(-t*0.0001)

fig, ax = plt.subplots()

ax.tick_params(axis='both', which='major')
plt.plot(t,s)

fmt = FuncFormatter(lambda x, pos: tickformat(x / 1e3))
ax.xaxis.set_major_formatter(fmt)

plt.xlabel('time ($s 10^3$)')

plt.show()

Note that the example manipulates the x-axis!

Of course, this could be achieved even simpler by re-scaling the data. However, I assume you don't want to touch the data and only manipulate the axis.




回答2:


I do not see an obvious way to do this via the knobs that exist on ScalarFormatter. Something like this:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mticker

t = np.arange(0.0, 10000.0, 10.)
s = np.sin(np.pi*t)*np.exp(-t*0.0001)

class EpiCycleScalarFormatter(mticker.ScalarFormatter):
    def _set_orderOfMagnitude(self, rng):
        # can just be super() in py3, args only needed in LPy
        super(EpiCycleScalarFormatter, self)._set_orderOfMagnitude(rng)
        if self.orderOfMagnitude != 0:
            self.orderOfMagnitude -= 1


fig, ax = plt.subplots()

ax.tick_params(axis='both', which='major')
ax.yaxis.set_major_formatter(EpiCycleScalarFormatter())
ax.xaxis.set_major_formatter(EpiCycleScalarFormatter())
plt.ticklabel_format(style='sci', axis='x', scilimits=(0,3))
plt.
plt.show()plot(t,s)

will solve your problem. Note the name of the sub-class, as this is just adding epicycles (they look like they work, but just add more complexity) to the existing code. This also touches private parts of the library which we may break at any time.



来源:https://stackoverflow.com/questions/34992685/plotting-with-scientific-axis-changing-the-number-of-significant-figures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!