如何在长度变化的轴上添加恒定间距的刻度? [蟒蛇]

时间:2011-06-27 14:14:22

标签: python graph matplotlib axis

为了简化我的问题(它不是那样的,但我更喜欢简单问题的简单答案):

我有几张描绘矩形区域区域的2D地图。我想添加地图轴和刻度以显示此地图上的距离(使用matplotlib,因为旧代码与它一起),但问题是区域大小不同。我想在轴上放置漂亮,清晰的刻度,但地图的宽度和高度可以是任何东西......

试图解释我的意思:假设我有一张面积为4.37 km * 6.42 km的地区地图。我希望在0,1,2,3和4 km上有x轴刻度:s和0,1,2,3,4,5和6 km上的y轴刻度:s。然而,由于该区域大于4 km * 6 km,因此图像和轴的距离远远超过4 km和6 km。

刻度线之间的间距可以是1 km。然而,地图的大小变化很大(比方说,在5-15公里之间),它们是浮动值。我当前的脚本知道区域的大小,并可以将图像缩放到正确的高度/宽度比,但如何告诉它在哪里放置滴答?

可能已经解决了这个问题,但由于我找不到合适的搜索词来解决我的问题,我不得不在这里问一下......

3 个答案:

答案 0 :(得分:5)

只需将刻度定位器设置为使用matplotlib.ticker.MultipleLocator(x),其中x是您想要的间距(例如,上例中为1.0)。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter

x = np.arange(20)
y = x * 0.1

fig, ax = plt.subplots()
ax.plot(x, y)

ax.xaxis.set_major_locator(MultipleLocator(1.0))
ax.yaxis.set_major_locator(MultipleLocator(1.0))

# Forcing the plot to be labeled with "plain" integers instead of scientific notation
ax.xaxis.set_major_formatter(FormatStrFormatter('%i'))

plt.show()

这样做的好处是,无论我们如何缩放或与绘图交互,它总是标有1个单位的刻度。 enter image description here

答案 1 :(得分:0)

这应该给你在x轴上当前轴限制内的所有整数值上打勾:

from matplotlib import pylab as plt
import math

# get values for the axis limits (unless you already have them)
xmin,xmax = plt.xlim()

# get the outermost integer values using floor and ceiling 
# (I need to convert them to int to avoid a DeprecationWarning),
# then get all the integer values between them using range
new_xticks = range(int(math.ceil(xmin)),int(math.floor(xmax)+1))
plt.xticks(new_xticks,new_xticks)
# passing the same argment twice here because the first gives the tick locations
# and the second gives the tick labels, which should just be the numbers

重复y轴。

出于好奇:默认情况下会得到什么样的滴答声?

答案 2 :(得分:0)

好的,我试过你的版本,但不幸的是我无法使它们工作,因为有一些缩放和PDF定位的东西使我(和你的代码建议)严重混淆。但通过测试它们,我再次学到了很多python,谢谢!

我终于找到了一个不太精确但满足我需求的解决方案。我就是这样做的。

在我的版本中,1 km除以一个名为STEP_PART的合适整数常量。 STEP_PART越大,轴值越精确(如果它太大,则读取的轴会变得混乱)。例如,如果STEP_PART为5,则精度为1 km / 5 = 200 m,并且每隔200 m进行一次滴答。

STEP_PART = 5             # In the start of the program.

height = 6.42             # These are actually given elsewhere,
width = 4.37              # but just as example...

vHeight = range(0, int(STEP_PART*height), 1)  # Make tick vectors, now in format
                                              # 0, 1, 2... instead of 0, 0.2...
vWidth = range(0, int(STEP_PART*width), 1)    # Should be divided by STEP_PART 
                                              # later to get right values.

为避免制作太多的轴标签(0,1,2 ......足够,0,0.2,0.4 ......太多),我们用字符串“”替换非整数km值。同时,我们通过STEP_PART划分整数km值以获得正确的值。

for j in range(len(vHeight)):
    if (j % STEP_PART != 0):
        vHeight[j] = ""
    else:
        vHeight[j] = int(vHeight[j]/STEP_PART)

for i in range(len(vWidth)):
    if (i % STEP_PART != 0):
        vWidth[i] = ""
    else:
        vWidth[i] = int(vWidth[i]/STEP_PART)

稍后,在创建图形和轴之后,以这种方式放置刻度(以x轴为例)。在那里,x是图片的实际宽度,得到了shape()命令(我不完全理解如何...我正在修改的代码中存在相当多的缩放和内容。)

xt = np.linspace(0,x-1,len(vWidth)+1) # For locating those ticks on the same distances.
locs, labels = mpl.xticks(xt, vWidth, fontsize=9) 

重复y轴。结果是一个图表,其中每200米有一个滴答,但整数km值的数据标签。无论如何,这些轴的精度是200米,这不是确切的,但对我来说已经足够了。如果我发现如何增加整数滴答的大小,脚本会更好......