我正在尝试以对数刻度(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,2等? 我努力了,但我只能在Y轴上显示10,10²!
我需要在Y轴上显示全部原始值。 有什么想法吗?
答案 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()
答案 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中提到的任何其他解决方案。