7

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

在此处输入图像描述

4

2 回答 2

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()

这导致:

在此处输入图像描述

请注意'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()

结果如下图:

在此处输入图像描述

如您所见,我使用 x 和 y 中的刻度线来定义一系列我想要网格标记 ('+') 的点。我使用meshgrid两个 1D 数组并制作 2 个 2D 数组,这些数组对应于每个网格点上的双循环。我用标记样式将其绘制为'+',并且我已经完成了......几乎。这会在顶部绘制十字,并且我添加了一个额外的关键字来重新排序与绘图关联的线条列表。zorder如果要在所有内容后面绘制网格标记,我会调整它们。*****

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

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

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

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

在此处输入图像描述

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

于 2012-04-25T13:42:19.940 回答
3

您可以在刻度点的每个交点处绘制线段。它很容易做到,只需抓住get_ticklocs()两个轴的刻度位置,然后遍历所有组合,使用axhlineand绘制短线段axvline,从而在每个交叉点创建一个十字准线。我已经设置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()

在此处输入图像描述

于 2012-04-25T16:02:03.273 回答