Python 带零值的Matplotlib对数标度

Python 带零值的Matplotlib对数标度,python,matplotlib,logarithm,Python,Matplotlib,Logarithm,我有一个非常大且稀疏的垃圾邮件twitter账户数据集,它要求我缩放x轴,以便能够可视化各种变量的分布(直方图、kde等)和cdf(tweets_计数、关注者/关注者数量等) 在这个数据集中,值0具有巨大的重要性(实际上0应该具有最高的密度)。但是,对于对数刻度,这些值将被忽略。例如,我曾考虑将该值更改为0.1,但如果存在拥有10^-1追随者的垃圾邮件帐户,则毫无意义 那么,python和matplotlib中的解决方法是什么呢 ax1.set_xlim(0, 1e3) 以下是matplotl

我有一个非常大且稀疏的垃圾邮件twitter账户数据集,它要求我缩放x轴,以便能够可视化各种变量的分布(直方图、kde等)和cdf(tweets_计数、关注者/关注者数量等)

在这个数据集中,值0具有巨大的重要性(实际上0应该具有最高的密度)。但是,对于对数刻度,这些值将被忽略。例如,我曾考虑将该值更改为0.1,但如果存在拥有10^-1追随者的垃圾邮件帐户,则毫无意义

那么,python和matplotlib中的解决方法是什么呢

ax1.set_xlim(0, 1e3)
以下是matplotlib文档中的示例

在这里,它以这种方式设置轴的极限值:

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

为每个
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()


使用

根据
x
的非日志值重新标记记号

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


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

如果将所有x值增加1,因为
log(1)=0
,与
x=0
对应的点将不会在日志图上的
x=log(1)=0
处绘制


剩余的x值也将移动1,但这对眼睛来说无关紧要,因为
log(x+1)
非常接近
log(x)
对于较大的
x

值,如果您将轴/绘图代码放在适当的位置以便进行校正,那就太好了。使用
symlog
这不会显示如何在对数刻度上使用零值。由于日志(0)未定义,因此matplotlib将忽略这些值。将xlim设置为1e1将使x轴从0.1开始,但仍将忽略0(我相信)。无论如何,我会尝试一下,至少在2015年7月,matplotlib不会忽略零,它在对数图上画了一条直线,一直到图的边缘,看起来很糟糕,与matlab不匹配。海耶的评论对我来说似乎并不真实。是的,但我不能在我的论文中说50%的垃圾邮件发送者没有追随者。因为它将显示为10^0,这意味着它们有一个跟随者(这是不同的)。您可以使用
plt.xticks
重新标记记号。我编辑了这篇文章来展示如何。为了不转移所有的数据。如何有效地将0.1添加到0值,使其在10^-1处出现,然后重新标记刻度?我知道这是另一个问题。但这可能是一种在不污染所有数据的情况下执行此操作的更好方法—仅移动0个值(并且在大型numpy数组上循环非常慢),如果您有一个包含许多0个值的数组,则可以使用
x[xI]将其更改为0.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))