我经常发现自己在我的绘图的日志单元中工作,例如在装箱之前获取np.log10(x)
数据或创建等高线图。问题是,当我想要绘制图表时,轴是丑陋的对数单位,刻度线均匀分布。
如果我让matplotlib进行所有转换,即设置ax.set_xaxis('log')
,那么我会看到非常漂亮的轴,但是我不能对我的数据这样做,因为它是例如已经以日志单位分箱。我可以手动更改刻度标签,但这不会使刻度间距成对数。我想我也可以手动指定每个小刻度的位置,例如它有日志间距,但这是实现这一目的的唯一方法吗?这有点单调乏味,所以如果有更好的方法会很好。
我希望刻度标签为10^x
和10^y
(所以' 1'是' 10',2是' 100&# 39;等等),我希望绘制次要刻度,因为ax.set_xaxis('log')
会绘制它们。
编辑:为了进一步具体化,假设绘图是从图像生成的,如下所示:
import matplotlib.pyplot as plt
import scipy.misc
img = scipy.misc.face()
x_range = [-5,3] # log10 units
y_range = [-55, -45] # log10 units
p = plt.imshow(img,extent=x_range+y_range)
plt.show()
我们要做的就是改变轴的外观,如我所描述的那样。
编辑2:好的,重要性的回答欧文斯特的答案非常聪明,但它对图像的要求比我想要的要多一些。我有另一个例子,这次是分箱数据。也许他们的技术仍然适用于此,但我不清楚是否是这种情况。
import numpy as np
import pandas as pd
import datashader as ds
from matplotlib import pyplot as plt
import scipy.stats as sps
v1 = sps.lognorm(loc=0, scale=3, s=0.8)
v2 = sps.lognorm(loc=0, scale=1, s=0.8)
x = np.log10(v1.rvs(100000))
y = np.log10(v2.rvs(100000))
x_range=[np.min(x),np.max(x)]
y_range=[np.min(y),np.max(y)]
df = pd.DataFrame.from_dict({"x": x, "y": y})
#------ Aggregate the data ------
cvs = ds.Canvas(plot_width=30, plot_height=30, x_range=x_range, y_range=y_range)
agg = cvs.points(df, 'x', 'y')
# Create contour plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.contourf(agg, extent=x_range+y_range)
ax.set_xlabel("x")
ax.set_ylabel("y")
plt.show()
答案 0 :(得分:2)
这个问题的一般答案可能在这篇文章中给出:
Can I mimic a log scale of an axis in matplotlib without transforming the associated data?
但是这里一个简单的选项可能是缩放轴的内容,然后将轴设置为对数刻度。
您可以在对数刻度上绘制图像,但以日志单位使所有像素的大小相同。很遗憾,imshow
不允许使用此类图像(any more),但可以使用pcolormesh
来实现此目的。
import numpy as np
import matplotlib.pyplot as plt
import scipy.misc
img = scipy.misc.face()
extx = [-5,3] # log10 units
exty = [-45, -55] # log10 units
x = np.logspace(extx[0],extx[-1],img.shape[1]+1)
y = np.logspace(exty[0],exty[-1],img.shape[0]+1)
X,Y = np.meshgrid(x,y)
c = img.reshape((img.shape[0]*img.shape[1],img.shape[2]))/255.0
m = plt.pcolormesh(X,Y,X[:-1,:-1], color=c, linewidth=0)
m.set_array(None)
plt.gca().set_xscale("log")
plt.gca().set_yscale("log")
plt.show()
相同的概念可用于等高线图。
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(-1.1,1.9)
y = np.linspace(-1.4,1.55)
X,Y = np.meshgrid(x,y)
agg = np.exp(-(X**2+Y**2)*2)
fig, ax = plt.subplots()
plt.gca().set_xscale("log")
plt.gca().set_yscale("log")
exp = lambda x: 10.**(np.array(x))
cf = ax.contourf(exp(X), exp(Y),agg, extent=exp([x.min(),x.max(),y.min(),y.max()]))
ax.set_xlabel("x")
ax.set_ylabel("y")
plt.show()