我想用Python绘制一个平方根比例的图:
但是,我不知道怎么做。Matplotlib允许进行对数缩放,但在这种情况下,我需要像幂函数缩放这样的东西。
发布于 2017-02-16 16:44:33
您可以创建自己的ScaleBase
类来执行此操作。为了您的目的,我已经修改了here中的示例(它生成的是平方刻度,而不是平方根刻度)。另请参阅文档here。
请注意,要正确地完成此操作,您可能还应该创建自己的自定义计时定位器;但我在这里没有这样做;我只是使用ax.set_yticks()
手动设置主要计时和次要计时。
import matplotlib.scale as mscale
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
import matplotlib.ticker as ticker
import numpy as np
class SquareRootScale(mscale.ScaleBase):
"""
ScaleBase class for generating square root scale.
"""
name = 'squareroot'
def __init__(self, axis, **kwargs):
# note in older versions of matplotlib (<3.1), this worked fine.
# mscale.ScaleBase.__init__(self)
# In newer versions (>=3.1), you also need to pass in `axis` as an arg
mscale.ScaleBase.__init__(self, axis)
def set_default_locators_and_formatters(self, axis):
axis.set_major_locator(ticker.AutoLocator())
axis.set_major_formatter(ticker.ScalarFormatter())
axis.set_minor_locator(ticker.NullLocator())
axis.set_minor_formatter(ticker.NullFormatter())
def limit_range_for_scale(self, vmin, vmax, minpos):
return max(0., vmin), vmax
class SquareRootTransform(mtransforms.Transform):
input_dims = 1
output_dims = 1
is_separable = True
def transform_non_affine(self, a):
return np.array(a)**0.5
def inverted(self):
return SquareRootScale.InvertedSquareRootTransform()
class InvertedSquareRootTransform(mtransforms.Transform):
input_dims = 1
output_dims = 1
is_separable = True
def transform(self, a):
return np.array(a)**2
def inverted(self):
return SquareRootScale.SquareRootTransform()
def get_transform(self):
return self.SquareRootTransform()
mscale.register_scale(SquareRootScale)
fig, ax = plt.subplots(1)
ax.plot(np.arange(0, 9)**2, label='$y=x^2$')
ax.legend()
ax.set_yscale('squareroot')
ax.set_yticks(np.arange(0,9,2)**2)
ax.set_yticks(np.arange(0,8.5,0.5)**2, minor=True)
plt.show()
发布于 2021-10-18 01:19:16
这是旧的,但我做了一个快速修复,因为我不想创建一个自定义的滴答定位器。如果您正在使用自定义比例制作大量绘图,这可能是可行的方法。只需使用所需的比例绘制函数,然后设置刻度和更改标签,如果只需要一两个绘图,则会更快。
Nx = 100
x = np.linspace(0,50,Nx)
y = np.sqrt(x)
fig, ax = plt.subplots(1, 1)
plt.plot(np.sqrt(x), y)
ax.set_xticks([np.sqrt(x[i]) for i in range(0, Nx, Nx // 10)])
ax.set_xticklabels([str(round(x[i],0))[:-2] for i in range(0, Nx, Nx // 10)])
plt.xlabel('x')
plt.ylabel(r'y = $\sqrt{x}$')
plt.grid()
plt.show()
生成绘图
发布于 2017-02-16 17:10:28
我喜欢lolopop的评论和tom的回答,一个更快更脏的解决方案是使用set,如下所示:
x = np.arange(2, 15, 2)
y = x * x
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax1.plot(x,y)
ax2.plot(x, np.sqrt(y))
ax2.set_yticks([2,4,6,8,10,12,14])
ax2.set_yticklabels(['4','16','36','64','100','144','196'])
https://stackoverflow.com/questions/42277989
复制相似问题