简体   繁体   English

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

[英]Plotting diagonal grid lines, with a variable angle of intersecting lines

I am trying to plot some diagonal grid lines on a plot of random data for now.我现在正在尝试在随机数据的 plot 上 plot 一些对角网格线。 I am currently able to produce 90 degree intersecting lines, but I am unsure how to produce anything other than that angle.我目前能够制作 90 度相交线,但我不确定如何制作除该角度之外的任何东西。 Here is the code:这是代码:

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

plot to show 90 degree intersecting grid lines, want to make that angle a variable one, say 25 degree or 60 plot 显示 90 度相交的网格线,想要使该角度可变,例如 25 度或 60 度

Ideally, I would like to incorporate this into a function that I can specify the intersecting degree and the number of lines in the plot.理想情况下,我想将其合并到 function 中,我可以在 plot 中指定相交度和行数。

You have a lot of repeating lines of code, which suggests that a loop can be a sensible approach.您有很多重复的代码行,这表明循环可能是一种明智的方法。 The coordinates also follow a strict geometrical pattern, so can be calculated mathematically.坐标也遵循严格的几何模式,因此可以进行数学计算。

In my answer below I used a loop and some trigonometry to generate the coordinates automatically.在下面的回答中,我使用了一个循环和一些三角函数来自动生成坐标。 Your definition of "intersecting degree" of angle is ambiguous - is it top/bottom angle or the left/right angle?您对角度“相交度”的定义是模棱两可的 - 是顶角/底角还是左/右角? I assumed it is the former in my solution.我认为这是我的解决方案中的前者。

If you are keen to understand the geometrical reasoning, sketch a right-angled triangle, such as here .如果您热衷于理解几何推理,请绘制一个直角三角形,例如此处 On that sketch side b is 1 and side a is tan(A) .在该草图上, b侧为 1 , a侧为tan(A) That should help you.那应该对你有帮助。

This might be possible using matplotlib built-ins, but I am not sure.这可能使用 matplotlib 内置插件,但我不确定。 I just adapted your approach and automated it.我刚刚调整了您的方法并将其自动化。

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

EDIT: A modification to the line-drawing to ensure that the lines cross on the left side of the screen.编辑:对线条图的修改,以确保线条在屏幕左侧交叉。 Looks nicer and would make it easier to make it align with specific axis ticks if necessary:看起来更好,并且在必要时更容易使其与特定的轴刻度对齐:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM