2013-08-28 47 views
3

使用从先前讨论的相同的代码的刻度标记,该样品产生下图:matplotlib命名上x轴1,2,4,8,16,等等

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 

data = (0, 1890,865, 236, 6, 1, 2, 0 , 0, 0, 0 ,0 ,0 ,0, 0, 0) 
ind = range(len(data)) 
width = 0.9 # the width of the bars: can also be len(x) sequence 

p1 = plt.bar(ind, data, width) 
plt.xlabel('Duration 2^x') 
plt.ylabel('Count') 
plt.title('DBFSwrite') 
plt.axis([0, len(data), -1, max(data)]) 

ax = plt.gca() 

ax.spines['right'].set_visible(False) 
ax.spines['top'].set_visible(False) 
ax.spines['left'].set_visible(False) 
ax.spines['bottom'].set_visible(False) 

plt.savefig('myfig') 

Sample output

而不是刻度标签是0,2,4,6,8 ......我宁愿让它们在每个标记处都标记,然后继续2^x:1,2,4,8,16等等的值。 我怎样才能做到这一点?然后,甚至更好,我可以将标签置于酒吧下方,而不是在左边缘?

回答

5

一个实现这一目标是利用一个LocatorFormatter的方式。这使得交互式地使用绘图而不会“丢失”标记成为可能。在这种情况下,我推荐使用MultipleLocatorFuncFormatter,如下例所示。

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 
from matplotlib.ticker import MultipleLocator, FuncFormatter 

data = (0, 1890,865, 236, 6, 1, 2, 0 , 0, 0, 0 ,0 ,0 ,0, 0, 0) 
ind = range(len(data)) 
width = 0.9 # the width of the bars: can also be len(x) sequence 

# Add `aling='center'` to center bars on ticks 
p1 = plt.bar(ind, data, width, align='center') 
plt.xlabel('Duration 2^x') 
plt.ylabel('Count') 
plt.title('DBFSwrite') 
plt.axis([0, len(data), -1, max(data)]) 

ax = plt.gca() 

# Place tickmarks at every multiple of 1, i.e. at any integer 
ax.xaxis.set_major_locator(MultipleLocator(1)) 
# Format the ticklabel to be 2 raised to the power of `x` 
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: int(2**x))) 
# Make the axis labels rotated for easier reading 
plt.gcf().autofmt_xdate() 

ax.spines['right'].set_visible(False) 
ax.spines['top'].set_visible(False) 
ax.spines['left'].set_visible(False) 
ax.spines['bottom'].set_visible(False) 

plt.savefig('myfig') 

enter image description here

+0

+1对于不依赖pyplot的解决方案 –

+0

@PhillipCloud我不明白你的评论。 – tacaswell

+0

@tcaswell我的错误。我认为'FuncFormatter'和'MultipleLocator'不是'pyplot'的一部分,事实证明它们是用'pyplot'导入的。 –

5

xticks()是你想要什么:

# return locs, labels where locs is an array of tick locations and 
# labels is an array of tick labels. 
locs, labels = xticks() 

# set the locations of the xticks 
xticks(arange(6)) 

# set the locations and labels of the xticks 
xticks(arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue')) 

因此,有蜱在2^X为1..4 X,请执行以下操作:

tick_values = [2**x for x in arange(1,5)] 

xticks(tick_values,[("%.0f" % x) for x in tick_values]) 

要使标签在调用bar时使用align='center'而不是左侧的酒吧。

这里的结果:

the resulting graph

+2

+1在一个侧面说明,有没有必要做'[2 ** X在人气指数X(1,5)]'它更有效地只是做'2 * * arange(1,5)'。 –

+0

噢,谢谢你指出这一点!这只是我爱上了列表解析,所以我会尽可能地使用它们;) – ThePhysicist

+0

是的,但是你应该更爱上numpy;) – tacaswell