Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing hatch filled rectangles with differing angles in python

Tags:

python

drawing

I'm trying to draw a 2D rectangular plate in python. This plate will be split into a variable number of sections, each of these sections will be filled with a hatched pattern. This hatched pattern will have a specified angle. As an example for a rectangle with 5 sections and an array of its section hatch orientation (in degrees) being [0, 45, 0, -45, 0] is shown below. It will need to be able to display any orientation, not just the usual 90, 45, 0, i.e. 33, 74.5 etc.

enter image description here

Any idea how I could do this? Essentially I just want to show the orientation in each section, any other methods of expressing the same results would be much appreciated e.g. a single line instead of hatched.

Edit (after question was answered): Edited script provided by Greg is shown below.

from numpy import cos, sin
import numpy as np
import matplotlib.pyplot as plt

angles = [0,10,20,30,40,50]

numberOfSections = len(angles)

def plot_hatches(ax, angle, offset=.1):
    angle_radians = np.radians(angle)
    x = np.linspace(-1, 1, 10)
    for c in np.arange(-2, 2, offset):
        yprime = cos(angle_radians) * c - sin(angle_radians) * x
        xprime = sin(angle_radians) * c + cos(angle_radians) * x
        ax.plot(xprime, yprime, color="b", linewidth=2)
    ax.set_ylim(0, 1)
    ax.set_xlim(0, 1)
    return ax

fig, axes = plt.subplots(nrows=1, ncols=numberOfSections, figsize=(16,(16/numberOfSections)), sharex=True, sharey=True)

for i in range(len(axes.flat)):
    plot_hatches(axes.flat[i], angles[i])

fig.subplots_adjust(hspace=0, wspace=0)  
plt.show()

Produces an figure shown below. enter image description here But on inspection the angles do not match the input angles.

like image 775
user2739143 Avatar asked Oct 02 '22 22:10

user2739143


1 Answers

I have a basic idea although I suspect you will need to do quite a bit more depending how flexible you want the result to be.

from numpy import cos, sin
import numpy as np
import matplotlib.pyplot as plt

def plot_hatches(ax, angle, offset=.1):
    angle_radians = np.radians(angle)
    x = np.linspace(-2, 2, 10)
    for c in np.arange(-2, 2, offset):
        yprime = cos(angle_radians) * c + sin(angle_radians) * x
        xprime = sin(angle_radians) * c - cos(angle_radians) * x
        ax.plot(xprime, yprime, color="k")
    ax.set_ylim(0, 1)
    ax.set_xlim(0, 1)
    return ax


fig, axes = plt.subplots(nrows=4, ncols=4, figsize=(8,8), sharex=True, sharey=True)

for i in range(len(axes.flat)):
    plot_hatches(axes.flat[i], np.random.uniform(0, 90))

fig.subplots_adjust(hspace=0, wspace=0)   

There is two things parts here: firstly a function plot_hatches which draws hatches over the unit square on the axes ax. This is done by taking a single line x, y=c and rotating it using rotation matrix to get a xprime and yprime which are the coordinates of lines at an angle to the x axis with offset c. Iterating over several values of c covers the unit square, the lines can be made denser by making the offset argument smaller.

Secondly we need a method to draw the axes next to each other. This I have done using subplots. This returns fig, axes the axes is an array of axes instances, so we iteratate through them passing them into the function to plot hatches and give it a random angle each time.

enter image description here

EDIT I have changed the plot_hatches code to rotate in an anticlockwise manner (it was clockwise before this edit). This will now produce exactly the image given in the question with the array [0, -45, 0, 45, 0]: enter image description here

like image 181
Greg Avatar answered Oct 05 '22 09:10

Greg