绘制对角线网格线,具有可变的相交线角度



我现在正在尝试在随机数据图上绘制一些对角线网格线。我目前能够产生 90 度相交线,但我不确定如何产生该角度以外的任何东西。 这是代码:

import numpy as np
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(6, 6))
mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1
ax.scatter(x, y, c=".3")
ax.plot([0, 1], [0, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.1, 1], [0, 0.9], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.2, 1], [0, 0.8], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.3, 1], [0, 0.7], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.4, 1], [0, 0.6], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.5, 1], [0, 0.5], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.6, 1], [0, 0.4], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.7, 1], [0, 0.3], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.8, 1], [0, 0.2], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([0.9, 1], [0, 0.1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.1, 1], [0, 1.1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.2, 1], [0, 1.2], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.3, 1], [0, 1.3], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.4, 1], [0, 1.4], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.5, 1], [0, 1.5], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.6, 1], [0, 1.6], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.7, 1], [0, 1.7], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.8, 1], [0, 1.8], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-0.9, 1], [0, 1.9], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([-1, 1], [0, 2], transform=ax.transAxes, color='black', linewidth=0.5)

ax.plot([1, 0], [0, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.9], [0.9, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.8], [0.8, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.7], [0.7, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.6], [0.6, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.5], [0.5, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.4], [0.4, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.3], [0.3, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.2], [0.2, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, 0.1], [0.1, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.9], [-0.9, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.8], [-0.8, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.7], [-0.7, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.6], [-0.6, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.5], [-0.5, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.4], [-0.4, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.3], [-0.3, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.2], [-0.2, 1], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([1, -0.1], [-0.1, 1], transform=ax.transAxes, color='black', linewidth=0.5)
plt.show()

图显示 90 度相交的网格线,希望使该角度成为可变角度,例如 25 度或 60 度

理想情况下,我想将其合并到一个函数中,我可以指定图中的相交度和线数。

你有很多重复的代码行,这表明循环可能是一种明智的方法。坐标也遵循严格的几何模式,因此可以用数学方式计算。

在下面的回答中,我使用了一个循环和一些三角函数来自动生成坐标。您对角度"相交度"的定义是模棱两可的——是顶部/底部角度还是左/右角度?我假设它是我的解决方案中的前者。

如果您热衷于了解几何推理,请草绘一个直角三角形,例如此处。在该草图上,b面为1,a面为tan(A(。这应该对你有所帮助。

这可能使用 matplotlib 内置,但我不确定。我只是调整了您的方法并使其自动化。

import numpy as np
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(6, 6))
mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1
ax.scatter(x, y, c=".3")
intersecting_angle = 30  # the top/bottom angle of intersection of the lines
horizontal_angle = (180-intersecting_angle)/2  # calculated angle from horizontal
num_of_lines = 20  # number of lines to be visible on the screen in each direction.
gap = (1+ np.tan(np.deg2rad(horizontal_angle)))/num_of_lines  # calculated gap between lines
for i in range(num_of_lines):  # we know how many lines we want to repeat this for
for direction in [-1, 1]:  # some of the lines go above the x axis, some will go below to draw in that empty area on the right.
startx = 0  # all lines start at the leftmost part of the screen
starty = 0 + gap*i*direction  # lines are spaced by the same gap vertically
endx = 1  # all lines end at the rightmost part of the screen
endy = np.tan(np.deg2rad(horizontal_angle)) + gap*i*direction  # trig used to calculate the end y-coordinate for the given angle
# a line is drawn from left to right upwards
ax.plot([startx, endx], [starty, endy], transform=ax.transAxes, color='black', linewidth=0.5)
# a line is drawn from left to right downwards
ax.plot([startx, endx], [endy, starty], transform=ax.transAxes, color='black', linewidth=0.5)

plt.show()

编辑:对线条绘制的修改,以确保线条在屏幕左侧交叉。看起来更好,如有必要,可以更轻松地使其与特定轴刻度对齐:

### LIBRARY AND SETUP STUFF ###
for i in range(num_of_lines):
for direction in [-1, 1]:
startx = 0
starty = 0 + gap*i*direction
endx = 1
endy = np.tan(np.deg2rad(horizontal_angle)) + gap*i*direction
endy_flip = -np.tan(np.deg2rad(horizontal_angle)) + gap*i*direction
ax.plot([startx, endx], [starty, endy], transform=ax.transAxes, color='black', linewidth=0.5)
ax.plot([startx, endx], [starty, endy_flip], transform=ax.transAxes, color='black', linewidth=0.5)

最新更新