【问题标题】:logarithmic scale in PythonPython中的对数刻度
【发布时间】:2017-09-22 22:50:09
【问题描述】:

我正在尝试以对数刻度(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

但结果是:

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

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

【问题讨论】:

  • 你想要y轴上的什么值?
  • @wwii:我需要显示所有真实值:3,195,200,...203
  • @wwii:使用对数刻度可以吗?
  • 像 210、220、230 和 240 这样的数字在对数刻度上非常接近,以至于它们的文本可能会重叠。
  • @wwii:所以,我想显示值的最大数量!

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


【解决方案1】:

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刻度格式documentation

【讨论】:

  • 谢谢,但它没有显示所有实际值:263,170 ... Y 轴。那可能吗? -> ufile.io/lzxbc
  • 我觉得这些会更好地显示在栏本身上,matplotlib gives a good example bar chart which might help
  • 谢谢。你能帮忙显示 Y 轴上的真实值吗?我觉得会更好!
  • 似乎涉及的比较多,如果到时候没人有解决方案,早上再看看
【解决方案2】:

问题似乎是如何在 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()

【讨论】:

    【解决方案3】:

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

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

    在运行时确定对数刻度的主要刻度;找出数据中十的最大幂,然后制作它下面的所有十的幂。:

    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)])
    

    【讨论】:

    • 在查看了这个答案、问题和其他答案之后,我想知道为什么它被接受了。
    【解决方案4】:

    有趣的是,我在SO in portuguese 中解决了这个问题。

    除了ImportanceOfBeingErnest的答案,还可以加

    plt.gca().minorticks_off()
    

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-09-07
      • 2011-11-01
      • 1970-01-01
      • 2013-09-17
      • 1970-01-01
      • 2012-12-03
      • 2013-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多