Matplotlib轴限制和文本位置独立于数据集单元

时间:2015-12-16 20:46:18

标签: python matplotlib

尽管来自不同的数据集,我正在尝试制作格式相同的图表,但我遇到的问题是获得一致的文本位置和适当的轴限制,因为数据集的缩放比例并不完全相同。例如 - 假设我生成以下高程配置文件:

import matplotlib.pyplot as plt
import numpy as np

Distance=np.array([1000,3000,7000,15000,20000])
Elevation=np.array([100,200,350,800,400])

def MyPlot(X,Y):
    fig = plt.figure()
    ax = fig.add_subplot(111, aspect='equal')
    ax.plot(X,Y)
    fig.set_size_inches(fig.get_size_inches()*2)
    ax.set_ylim(min(Y)-50, max(Y)+500)
    ax.set_xlim(min(X)-50, max(X)+50)

    MaxPoint=X[np.argmax(Y)], max(Y)
    ax.scatter(MaxPoint[0], MaxPoint[1], s=10)
    ax.text(MaxPoint[0], MaxPoint[1]+100, s='Maximum = '+str(MaxPoint[1]), fontsize=8)

MyPlot(Distance,Elevation)  

enter image description here

然后我有另一个不同的数据集:

Distance2=Distance*4
Elevation2=Elevation*5
MyPlot(Distance2,Elevation2)][2]][2]

enter image description here

由于第一个数据集中的单位变化比第二个数据集大得多,因此文本和轴标签不会像我在第二个图中那样进行格式化。有没有办法调整文本位置和轴限制,以调整数据集的相对比例?

2 个答案:

答案 0 :(得分:2)

首先,对于放置带有此类偏移的文本,您几乎不想使用text。相反,请使用annotate。优点是您可以在 points 而不是数据单元中给出文本的偏移量。

接下来,要降低刻度线位置的密度,请使用ax.locator_params并更改nbins参数。 nbins控制刻度密度。刻度线位置仍会自动选择,但减少nbins将减少刻度线位置的最大数量。如果降低nbins,则可能还需要更改matplotlib在选择滴答间隔时认为“均匀”的数字。这样,您可以有更多选项来获得预期的滴答数。

最后,为避免使用set padding手动设置限制,请考虑使用margins(some_percentage)以当前限制的百分比填充范围。

显示所有的完整示例:

import matplotlib.pyplot as plt
import numpy as np

distance=np.array([1000,3000,7000,15000,20000])
elevation=np.array([100,200,350,800,400])

def plot(x, y):
    fig, ax = plt.subplots(figsize=(8, 2))

    # Plot your data and place a marker at the peak location
    maxpoint=x[np.argmax(y)], max(y)
    ax.scatter(maxpoint[0], maxpoint[1], s=10)
    ax.plot(x, y)

    # Reduce the maximum number of ticks and give matplotlib more flexibility
    # in the tick intervals it can choose.
    # Essentially, this will more or less always have two ticks on the y-axis
    # and 4 on the x-axis
    ax.locator_params(axis='y', nbins=3, steps=range(1, 11))
    ax.locator_params(axis='x', nbins=5, steps=range(1, 11))

    # Annotate the peak location. The text will always be 5 points from the
    # data location.
    ax.annotate('Maximum = {:0.0f}'.format(maxpoint[1]), size=8,
                xy=maxpoint, xytext=(5, 5), textcoords='offset points')

    # Give ourselves lots of padding on the y-axis, less on the x
    ax.margins(x=0.01, y=0.3)
    ax.set_ylim(bottom=y.min())

    # Set the aspect of the plot to be equal and add some x/y labels
    ax.set(xlabel='Distance', ylabel='Elevation', aspect=1)
    plt.show()

plot(distance,elevation)

enter image description here

如果我们改变数据:

plot(distance * 4, elevation * 5)

enter image description here

最后,您可以考虑将注释放在轴顶部的上方,而不是从该点偏移:

ax.annotate('Maximum = {:0.0f}'.format(maxpoint[1]), ha='center',
            size=8, xy=(maxpoint[0], 1), xytext=(0, 5),
            textcoords='offset points',
            xycoords=('data', 'axes fraction'))

enter image description here

答案 1 :(得分:-2)

可能你应该使用seaborn没有任何边界。我认为这是非常好的方式。 它看起来像这样: ok

你应该在脚本的开头写一个字符串import seaborn