而不是绘图上的网格线,matplotlib打印网格十字架?

时间:2012-04-25 11:45:18

标签: python matplotlib

我想在绘图上有一些网格线,但实际上全长线太多/分散注意力,甚至是浅灰色线条。我去手动对SVG输出进行了一些编辑,以获得我想要的效果。这可以用matplotlib完成吗?我看了一下网格的pyplot api,我能看到的唯一可以接近它的是xdata和ydata Line2D kwargs。

enter image description here

2 个答案:

答案 0 :(得分:3)

这不能通过基本API完成,因为网格线仅使用两个点创建。网格线在每个刻度标记处都需要一个“数据”点,以便绘制标记。这在以下示例中显示:

import matplotlib.pyplot as plt

ax = plt.subplot(111)
ax.grid(clip_on=False, marker='o', markersize=10)
plt.savefig('crosses.png')
plt.show()

这导致:

enter image description here

注意'o'标记仅在Axes边的开头和结尾处,因为网格线只涉及两个点。

您可以编写一个方法来模拟您想要的内容,使用一系列Artists创建交叉标记,但只需利用基本绘图功能绘制交叉模式就可以更快。

这就是我在以下示例中所做的:

import matplotlib.pyplot as plt
import numpy as np

NPOINTS=100

def set_grid_cross(ax, in_back=True):
    xticks = ax.get_xticks()
    yticks = ax.get_yticks()
    xgrid, ygrid = np.meshgrid(xticks, yticks)
    kywds = dict() 
    if in_back:
        kywds['zorder'] = 0
    grid_lines = ax.plot(xgrid, ygrid, 'k+', **kywds)

xvals = np.arange(NPOINTS)
yvals = np.random.random(NPOINTS) * NPOINTS

ax1 = plt.subplot(121)
ax2 = plt.subplot(122)

ax1.plot(xvals, yvals, linewidth=4)
ax1.plot(xvals, xvals, linewidth=7)
set_grid_cross(ax1)
ax2.plot(xvals, yvals, linewidth=4)
ax2.plot(xvals, xvals, linewidth=7)
set_grid_cross(ax2, in_back=False)

plt.savefig('gridpoints.png')
plt.show()

这导致下图:

enter image description here

如您所见,我在x和y中使用刻度线来定义一系列我想要网格标记('+')的点。我使用meshgrid获取两个1D数组,并在每个网格点上创建2个2D数组,对应于双循环。我用标记样式'+'来绘制它,我已经完成了......差不多了。这将十字架绘制在顶部,我添加了一个额外的关键字来重新排列与绘图相关的行列表。我调整网格标记的zorder是否要在所有内容后面绘制。*****

该示例显示左侧子图,默认情况下网格位于后面,右侧子图禁用此选项。如果您按照每个图中的绿线,您可以注意到差异。

如果您对边界上的网格交叉感到困扰,则可以在set_grid_cross中定义网格之前删除x和y的第一个和最后一个刻度线,如下所示:

xticks = ax.get_xticks()[1:-1] #< notice the slicing
yticks = ax.get_yticks()[1:-1] #< notice the slicing
xgrid, ygrid = np.meshgrid(xticks, yticks)

我在下面的示例中执行此操作,使用更大的不同标记来表达我的观点:

enter image description here

*****感谢@fraxel的回答指出了这一点。

答案 1 :(得分:3)

您可以在刻度点的每个交点处绘制线段。它很容易做到,只需抓住两个轴的刻度位置get_ticklocs(),然后遍历所有组合,使用axhlineaxvline绘制短线段,从而创建一个十字线路口。我已设置zorder=0,因此首先绘制十字准线,以便它们位于绘图数据的后面。它易于控制颜色/ alpha和十字线的大小。一些轻微的“陷阱”......在得到刻度线位置之前进行绘图..而且xminxmax参数似乎需要规范化。

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)    
ax.plot((0,2,3,5,5,5,6,7,8,6,6,4,3,32,7,99), 'r-',linewidth=4)

x_ticks = ax.xaxis.get_ticklocs()
y_ticks = ax.yaxis.get_ticklocs()    
for yy in y_ticks[1:-1]:
    for xx in x_ticks[1:-1]:
        plt.axhline(y=yy, xmin=xx / max(x_ticks) - 0.02, 
                xmax=xx / max(x_ticks) + 0.02, color='gray', alpha=0.5, zorder=0)
        plt.axvline(x=xx, ymin=yy / max(y_ticks) - 0.02, 
                ymax=yy / max(y_ticks) + 0.02, color='gray', alpha=0.5, zorder=0)
plt.show()

enter image description here