我正在使用pylab.plot()将不同的数据集绘制到一个图形中,效果很好。但是,一个数据集的值介于0%和25%之间,另一个数据集的值介于75%和100%之间。我想在y轴上跳过30%到70%以节省一些空间。您对pyplot如何使用有任何建议吗?
编辑:
为清楚起见,我添加了以下图表。我想在y轴上跳过30%到60%,这样红线和绿线就会越来越近。
答案 0 :(得分:1)
解决方案基于Space_C0wb0ys post。
fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot( range(1,10), camean - 25, 'ro-' )
ax.plot( range(1,10), oemean , 'go-' )
ax.plot( range(1,10), hlmean , 'bo-' )
ax.set_yticks(range(5, 60, 5))
ax.set_yticklabels(["5","10","15","20","25","30","...","65","70","75"])
ax.legend(('ClassificationAccuracy','One-Error','HammingLoss'),loc='upper right')
pylab.show()
此代码创建以下图形。
答案 1 :(得分:0)
您可以从第二个函数的x值中减去40,以使x值的范围连续。这将为您提供0%至70%的范围。然后你可以按如下方式设置x轴的抽搐和实验:
x_ticks = range(71, 0, 10)
a.set_xticks(x_ticks)
a.set_xticklabels([str(x) for x in [0, 10, 20, 30, 70, 80, 90, 100]])
a
是当前轴。所以基本上,你将函数绘制在0%到70%的范围内,但是用一个间隙标记轴。
举例说明 - 以下脚本:
from numpy import arange
import matplotlib.pyplot as plt
x1 = arange(0, 26) # first function
y1 = x1**2
x2 = arange(75, 100) # second function
y2 = x2*4 + 10
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x1, y1)
ax.plot(x2 - 40, y2) # shift second function 40 to left
ax.set_xticks(range(0, 61, 5)) # set custom x-ticks
# set labels for x-ticks - labels have the gap we want
ax.set_xticklabels([str(x) for x in range(0, 26, 5) + range(70, 101, 5)])
plt.show()
生成以下图表(请注意x标签):
答案 2 :(得分:0)
matplotlib 文档实际上有 an example 如何做到这一点。
基本思想是将绘图分成两个子图,在每个图上放置相同的图,然后更改每个图的轴以仅显示特定部分,然后使其看起来更好。
所以,让我们应用它。想象一下这是您的起始代码:
import matplotlib.pyplot as plt
import random, math
# Generates data
i = range(10)
x = [math.floor(random.random() * 5) + 67 for i in range(10)]
y = [math.floor(random.random() * 5) + 22 for i in range(10)]
z = [math.floor(random.random() * 5) + 13 for i in range(10)]
# Original plot
fig, ax = plt.subplots()
ax.plot(i, x, 'ro-')
ax.plot(i, y, 'go-')
ax.plot(i, z, 'bo-')
plt.show()
我们努力让x
与其他部分分开。
首先,我们要绘制同一个图形两次,一个在另一个之上。为此,绘图功能需要是通用的。现在它应该看起来像这样:
# Plotting function
def plot(ax):
ax.plot(i, x, 'ro-')
ax.plot(i, y, 'go-')
ax.plot(i, z, 'bo-')
# Draw the graph on two subplots
fig, (ax1, ax2) = plt.subplots(2, 1)
plot(ax1)
plot(ax2)
现在这看起来更糟,但我们可以更改每个轴的范围以专注于我们想要的。现在我只是选择我知道会捕获所有数据的简单范围,但我稍后会专注于使轴相等。
# Changes graph axes
ax1.set_ylim(65, 75) # Top graph
ax2.set_ylim(5, 30) # Bottom graph
这越来越接近我们正在寻找的东西。现在我们需要让它看起来更好一点:
# Hides the spines between the axes
ax1.spines.bottom.set_visible(False)
ax2.spines.top.set_visible(False)
ax1.xaxis.tick_top()
ax1.tick_params(labeltop=False) # Don't put tick labels at the top
ax2.xaxis.tick_bottom()
# Adds slanted lines to axes
d = .5 # proportion of vertical to horizontal extent of the slanted line
kwargs = dict(
marker=[(-1, -d), (1, d)],
markersize=12,
linestyle='none',
color='k',
mec='k',
mew=1,
clip_on=False
)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)
最后,让我们修复轴。在这里,您需要做一些数学运算并决定更多的布局。例如,也许我们想让顶部的图变小,因为底部的图有两条线。为此,我们需要更改子图的高度比例,如下所示:
# Draw the graph on two subplots
# Bottom graph is twice the size of the top one
fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [1, 2]})
最后,让轴匹配是个好主意。在这种情况下,因为底部图像的大小是顶部图像的两倍,我们需要更改一个的轴来反映这一点。这次我选择修改最上面的。底部的图表覆盖了 25 的范围,这意味着顶部的图表应该覆盖了 12.5 的范围。
# Changes graph axes
ax1.set_ylim(60.5, 73) # Top graph
ax2.set_ylim(5, 30) # Bottom graph
这对我来说已经足够了。如果您不希望刻度与虚线重叠,您可以更多地使用轴或刻度标签。
最终代码:
import matplotlib.pyplot as plt
import random, math
# Generates data
i = range(10)
x = [math.floor(random.random() * 5) + 67 for i in range(10)]
y = [math.floor(random.random() * 5) + 22 for i in range(10)]
z = [math.floor(random.random() * 5) + 13 for i in range(10)]
# Plotting function
def plot(ax):
ax.plot(i, x, 'ro-')
ax.plot(i, y, 'go-')
ax.plot(i, z, 'bo-')
# Draw the graph on two subplots
# Bottom graph is twice the size of the top one
fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [1, 2]})
plot(ax1)
plot(ax2)
# Changes graph axes
ax1.set_ylim(60.5, 73) # Top graph
ax2.set_ylim(5, 30) # Bottom graph
# Hides the spines between the axes
ax1.spines.bottom.set_visible(False)
ax2.spines.top.set_visible(False)
ax1.xaxis.tick_top()
ax1.tick_params(labeltop=False) # Don't put tick labels at the top
ax2.xaxis.tick_bottom()
# Adds slanted lines to axes
d = .5 # proportion of vertical to horizontal extent of the slanted line
kwargs = dict(
marker=[(-1, -d), (1, d)],
markersize=12,
linestyle='none',
color='k',
mec='k',
mew=1,
clip_on=False
)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)
plt.show()