Matplotlib对数刻度中的零值

5

我有一个非常庞大且稀疏的垃圾推特账户数据集,需要我扩展x轴以便能够可视化各种变量(推文数、粉丝/关注人数等)的分布(直方图、核密度估计等)和累积分布函数。

    > describe(spammers_class1$tweets_count)
  var       n   mean      sd median trimmed mad min    max  range  skew kurtosis   se
1   1 1076817 443.47 3729.05     35   57.29  43   0 669873 669873 53.23  5974.73 3.59

在这个数据集中,值为0非常重要(实际上应该具有最高密度)。然而,在对数刻度下,这些值被忽略了。我考虑将值更改为0.1,但是这样就没有意义了,因为会出现拥有10^-1个关注者的垃圾账户。
那么,在Python和Matplotlib中有什么解决方法?

1
如果您能提供您的坐标轴/绘图代码以便进行更正,那就太好了。 - Stephane Rolland
1
使用 symlog。https://dev59.com/1nA75IYBdhLWcg3wboUz - tacaswell
2个回答

2

将每个x值加1,然后取对数:

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

fig, ax = plt.subplots()
x = [0, 10, 100, 1000]
y = [100, 20, 10, 50]
x = np.asarray(x) + 1 
y = np.asarray(y)
ax.plot(x, y)
ax.set_xscale('log')
ax.set_xlim(x.min(), x.max())
ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x-1)))
ax.xaxis.set_major_locator(ticker.FixedLocator(x))
plt.show()

输入图像描述


使用

ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x-1)))
ax.xaxis.set_major_locator(ticker.FixedLocator(x))

将刻度标记重新标记为非对数值的x值。

(我最初的建议是使用plt.xticks(x,x-1),但这会影响所有轴。为了将更改隔离到一个特定的轴中,我将所有命令调用更改为ax,而不是调用plt。)


matplotlib将包含NaNinf-inf值的点删除。由于log(0)-inf,因此与x=0对应的点将从对数图中删除。

如果将所有x值增加1,由于log(1)=0,因此与x=0对应的点将不会在对数图上以x=log(1)=0绘制。

其余的x值也将向右移动一个单位,但对于大的x值,log(x+1)非常接近于log(x),因此眼睛看不出来。


你可以使用 plt.xticks 重新标记刻度线。我已经编辑了帖子以展示如何操作。 - unutbu
1
如果你有一个包含大量 0 值的数组,你可以通过 x[x<=0] = 0.1 将它们改为 0.1。请注意,如果该数组是 int 类型,则必须先将其转换为 float 类型:x = x.astype('float') - unutbu
1
我强烈反对在绘制图表之前修改数据。 - tacaswell
@tcaswell:请重新阅读我的回答。你到底反对什么? - unutbu
@tcaswell。我很困惑,您既反对修改数据,又推荐使用 symlogsymlog 是将部分数据在线性比例尺上绘制,将另一部分数据在对数比例尺上绘制。如果这不是绘图前的数据修改,那还有什么是呢? - unutbu
显示剩余5条评论

0
ax1.set_xlim(0, 1e3)

这里是来自matplotlib文档的示例

然后它通过以下方式设置轴的限制值:

ax1.set_xlim(1e1, 1e3)
ax1.set_ylim(1e2, 1e3)

4
这并没有展示如何在对数刻度上处理零值。因为log(0)是未定义的,所以matplotlib会忽略这些值。将xlim设置为1e1将使x轴从0.1开始,但仍然会忽略0(我认为)。不管怎样,我还是会试一下。 - amaatouq
至少在2015年7月,matplotlib没有忽略零值,在对数图上绘制一条直线直到图的边缘,这看起来很糟糕,与Matlab不符。Hayer的评论对我来说似乎不是真的。 - poleguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接