Python中的对数比例

时间:2017-09-22 22:50:10

标签: python python-2.7 python-3.x numpy matplotlib

我正在尝试以对数刻度(Y轴)绘制图形,但我需要在Y轴上显示所有原始值。

我使用了代码:

# -*- coding: utf-8 -*-

import math
import matplotlib.pyplot as plt
import matplotlib.dates as dates
from datetime import datetime, timedelta
import numpy as np 

x = []
y = []
with open("dataset.csv") as f:
    for l in f:
        X,Y = l.split(",") #separador eh a virgula
        x.append(float(X))
        y.append( float (Y))
        #y.append( math.log (float (Y)))

#x1 = [datetime.fromtimestamp(int(d)) for d in x]
x1 = [str(datetime.fromtimestamp(int(d)))[-8:] for d in x]
y_pos = [idx for idx, i in enumerate(y)]

plt.figure(figsize=(17,9))
plt.gca().xaxis.set_major_formatter(dates.DateFormatter('%m/%d/%Y %H:%M:%S'))

plt.bar(y_pos, y, align='edge', color="blue", alpha=0.5, width=0.5) # <--- EDICAO PRINCIPAL
plt.title("Values X Time")
plt.ylabel("Values")
plt.xlabel('Time')
plt.xticks(y_pos, x1, size='small',rotation=35, ha="right")
#plt.yticks(y)
#plt.yticks(np.arange(0,max(y),0.3))
#plt.yticks(np.arange(0,max(y)+5,1))
plt.yscale('log')
plt.ylim(ymax=sorted(y)[-1]+1) # valor maximo do eixo y
#plt.ylim(ymin=sorted(y)[0]-1) # valor minimo do eixo y

plt.show()

数据集位于:

     1491828000,3
    1491828060,195
    1491828120,220
    1491828180,240  
    1491828240,230  
    1491828300,238
    1491828360,310
    1491828420,280
    1491828480,263
    1491828540,271
    1491828600,282
    1491828660,302
    1491828720,298
    1491828780,257
    1491828840,245
    1491828900,200
    1491828960,170
    1491829020,138
    1491829080,59
    1491829140,39
    1491829200,48
    1491829260,95
    1491829320,151
    1491829380,155
    1491829440,175
    1491829500,93
    1491829560,25
    1491829620,3
    1491829680,185
    1491829740,233
    1491829800,210
    1491829860,86
    1491829920,32
    1491829980,46
    1491830040,51
    1491830100,201
    1491830160,129
    1491830220,116
    1491830280,105
    1491830340,200
    1491830400,203

但结果是:

I need the orignal values in Y axis

如何在Y轴(对数刻度)中显示原始值,而不是10,10,2等? 我努力了,但我只能在Y轴上显示10,10²!

我需要在Y轴上显示全部原始值。 有什么想法吗?

4 个答案:

答案 0 :(得分:3)

问题似乎是如何在y轴上显示所有y值作为条形,假设y轴是对数刻度。

虽然这可能没有多大意义,但由于标签重叠,这就是答案:

您可以使用FixedLocator设置标签的位置,使用ScalarFormatter将格式设置为正常的十进制数(而不是10的幂)。

plt.gca().yaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.unique(y)))
plt.gca().yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())

完整代码:

import matplotlib.pyplot as plt
import matplotlib.dates as dates
import matplotlib.ticker
from datetime import datetime, timedelta
import numpy as np 

x,y = np.loadtxt(io.StringIO(u), delimiter=",", unpack=True)

x1 = [str(datetime.fromtimestamp(int(d)))[-8:] for d in x]
y_pos = [idx for idx, i in enumerate(y)]

plt.figure(figsize=(17,9))
plt.gca().xaxis.set_major_formatter(dates.DateFormatter('%m/%d/%Y %H:%M:%S'))

plt.bar(y_pos, y, align='edge', color="blue", alpha=0.5, width=0.5) 
plt.title("Values X Time")
plt.ylabel("Values")
plt.xlabel('Time')
plt.xticks(y_pos, x1, size='small',rotation=35, ha="right")

plt.yscale('log')
plt.ylim(ymax=sorted(y)[-1]+1) # valor maximo do eixo y

plt.gca().yaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.unique(y)))
plt.gca().yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())

plt.show()

enter image description here

答案 1 :(得分:2)

Matplotlib自动收录器格式是您正在寻找的:

from matplotlib.ticker import FormatStrFormatter

...

plt.yscale('log')
plt.gca().yaxis.set_major_formatter(FormatStrFormatter('%.d')) #Here!
plt.ylim(ymax=sorted(y)[-1]+1) # valor maximo do eixo y

plt.show()

虽然可能有一种更简单的方法。使用matplotlibs tick格式documentation

找到

答案 2 :(得分:1)

您可以指定以太网x或y刻度位置。要将最大值添加到y轴,请使用.yticks()

plt.yscale('log')
plt.yticks([1,10,100] + [max(y)])
plt.gca().yaxis.set_major_formatter(FormatStrFormatter('%.d'))

确定运行时对数刻度的主要刻度;在数据中找到最大10的幂,然后使 10以下的所有权力。:

import math
...
exp = int(math.log10(max(y)))
majors = [10**x for x in range(exp+1)]
#majors = [10**n for n in range(len(str(max(y))))]
plt.yticks(majors + [max(y)])

答案 3 :(得分:1)

好笑,我在SO in portuguese中解决了这个问题。

ImportanceOfBeingErnest的答案外,您还可以添加

plt.gca().minorticks_off()

删除对数刻度的次刻度,因为它们重叠。因为我相信这会删除所有的小蜱,你可以使用另一种方法:

matplotlib.rcParams['xtick.minor.size'] = 0
matplotlib.rcParams['xtick.minor.width'] = 0

this question中提到的任何其他解决方案。