在 matplotlib 中自定义 x 轴 [英] Customize x-axis in matplotlib
问题描述
在下图中,x 轴上的每个单位代表一个 10 分钟的间隔.我想自定义 x 轴的标签,以便它显示小时,即每 6 个单位(60 分钟)显示一个自动收报机.我是matplotlib的新手.有人可以帮我吗?谢谢〜
In the figure below, each unit in the x-axis represents a 10mins interval. I would like to customize the labels of x-axis, so that it shows hours, i.e. it displays a ticker every 6 units (60mins). I am new to matplotlib. Could someone help me? Thanks~
这是上图的代码.
x = arange(0, size_x, dx)
y = arange(0, size_y, dy)
X,Y = meshgrid(x, y)
Z = foo(x,y)
pcolor(X, Y, Z, cmap=cm.Reds)
colorbar()
axis([0,size_x-1,0,size_y-1])
show()
推荐答案
有不止一种方法可以做到这一点.
There's more than one way to do this.
让我们从一个示例图开始:
Let's start out with an example plot:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
# Generate some data...
x, y = np.mgrid[:141, :101]
z = np.cos(np.hypot(x, y))
# Plot the figure...
plt.pcolormesh(x, y, z, cmap=mpl.cm.Reds)
plt.show()
做你想做的事情的简单方法是这样的:
The simple way to do what you want would be something like this:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
# Generate some data...
x, y = np.mgrid[:141, :101]
z = np.cos(np.hypot(x, y))
# Plot the figure...
plt.pcolormesh(x, y, z, cmap=mpl.cm.Reds)
# Set the ticks and labels...
ticks = np.arange(x.min(), x.max(), 6)
labels = range(ticks.size)
plt.xticks(ticks, labels)
plt.xlabel('Hours')
plt.show()
另一种方式涉及子类化 matplotlib 的定位器和代码.
The other way involves subclassing matplotlib's locators and tickers.
就您的目的而言,上面的示例很好.
For your purposes, the example above is fine.
制作新的定位器和自动报价器的优点是,轴将自动缩放为指定的"dx"单位的合理间隔.如果您将它用作更大应用程序的一部分,那么它可能是值得的.对于一个单一的情节,它比它的价值更麻烦.
The advantage of making new locators and tickers is that the axis will automatically be scaled into reasonable intervals of the "dx" units you specify. If you're using it as a part of a larger application, it can be worthwhile. For a single plot, it's more trouble than it's worth.
如果你真的想走那条路,你会做这样的事情:
If you really wanted to go that route, though, you'd do something like this:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
def main():
# Generate some data...
x, y = np.mgrid[:141, :101]
z = np.cos(np.hypot(x, y))
# Plot the figure...
fig, ax = plt.subplots()
ax.pcolormesh(x, y, z, cmap=mpl.cm.Reds)
ax.set_xlabel('Hours')
ax.xaxis.set_major_locator(ScaledLocator(dx=6))
ax.xaxis.set_major_formatter(ScaledFormatter(dx=6))
plt.show()
class ScaledLocator(mpl.ticker.MaxNLocator):
"""
Locates regular intervals along an axis scaled by *dx* and shifted by
*x0*. For example, this would locate minutes on an axis plotted in seconds
if dx=60. This differs from MultipleLocator in that an approriate interval
of dx units will be chosen similar to the default MaxNLocator.
"""
def __init__(self, dx=1.0, x0=0.0):
self.dx = dx
self.x0 = x0
mpl.ticker.MaxNLocator.__init__(self, nbins=9, steps=[1, 2, 5, 10])
def rescale(self, x):
return x / self.dx + self.x0
def inv_rescale(self, x):
return (x - self.x0) * self.dx
def __call__(self):
vmin, vmax = self.axis.get_view_interval()
vmin, vmax = self.rescale(vmin), self.rescale(vmax)
vmin, vmax = mpl.transforms.nonsingular(vmin, vmax, expander = 0.05)
locs = self.bin_boundaries(vmin, vmax)
locs = self.inv_rescale(locs)
prune = self._prune
if prune=='lower':
locs = locs[1:]
elif prune=='upper':
locs = locs[:-1]
elif prune=='both':
locs = locs[1:-1]
return self.raise_if_exceeds(locs)
class ScaledFormatter(mpl.ticker.OldScalarFormatter):
"""Formats tick labels scaled by *dx* and shifted by *x0*."""
def __init__(self, dx=1.0, x0=0.0, **kwargs):
self.dx, self.x0 = dx, x0
def rescale(self, x):
return x / self.dx + self.x0
def __call__(self, x, pos=None):
xmin, xmax = self.axis.get_view_interval()
xmin, xmax = self.rescale(xmin), self.rescale(xmax)
d = abs(xmax - xmin)
x = self.rescale(x)
s = self.pprint_val(x, d)
return s
if __name__ == '__main__':
main()
这篇关于在 matplotlib 中自定义 x 轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!