0

Example code:

fig, ax = plt.subplots()

ax.vlines(x=0.6, ymin=0.2, ymax=0.8, linewidth=10)
ax.hlines(y=0.2, xmin=0.2, xmax=0.6, linewidth=10)
ax.hlines(y=0.8, xmin=.6, xmax=0.8, linewidth=10)
ax.vlines(x=0.8, ymin=0.8, ymax=1.1, linewidth=10)
ax.hlines(y=1.1, xmin=.5, xmax=0.8, linewidth=10)
ax.vlines(x=0.5, ymin=0.4, ymax=1.1, linewidth=10)
ax.hlines(y=.4, xmin=.2, xmax=0.5, linewidth=10)

Which produces:

enter image description here

In the corners are gaps though, whereas I would like these to be flush.

To be clear, the corners currently look like:

enter image description here

Whereas I would like them to look like:

enter image description here

# Edit

Side note - if there's just a rectangle to be created the following can be used:

import matplotlib.patches as pt 
fig, ax = plt.subplots() 
frame = pt.Rectangle((0.2,0.2),0.4,0.6, lw=10,facecolor='none', edgecolor='k') 
ax.add_patch(frame)

More info on the edit here:

baxx
  • 3,956
  • 6
  • 37
  • 75

1 Answers1

2

Apart from plotting the lines as one segmented curve, an idea is to put a scatter dot at the start and end of each line segment. The size of a scatter dot is measured quadratic; a line width of 10 corresponds to a scatter size of about 70. Matplotlib also supports capstyle='round', which starts and ends the lines with a rounded cap. (For ax.plot, the parameter is named solid_capstyle='round', while for ax.vlinesit is justcapstyle='round').`

Other allowed values for capstyle are 'projecting' (extending the line with half its thickness) and 'butt' (stops the lines at the end point).

import matplotlib.pyplot as plt

fig, axs = plt.subplots(ncols=3, figsize=(15, 4))
for ax, capstyle in zip(axs, ['round', 'projecting', 'butt']):
    ax.vlines(x=0.6, ymin=0.2, ymax=0.8, linewidth=10, capstyle=capstyle)
    ax.hlines(y=0.2, xmin=0.2, xmax=0.6, linewidth=10, capstyle=capstyle)
    ax.hlines(y=0.8, xmin=.6, xmax=0.8, linewidth=10, capstyle=capstyle)
    ax.vlines(x=0.8, ymin=0.8, ymax=1.1, linewidth=10, capstyle=capstyle)
    ax.hlines(y=1.1, xmin=.5, xmax=0.8, linewidth=10, capstyle=capstyle)
    ax.vlines(x=0.5, ymin=0.4, ymax=1.1, linewidth=10, capstyle=capstyle)
    ax.hlines(y=.4, xmin=.2, xmax=0.5, linewidth=10, capstyle=capstyle)
    ax.set_title(f"capstyle='{capstyle}'")
plt.show()

line segments using round cap style

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • thanks - the corners are rounded on this rather than square as in the image, but it's still useful... Is it possible to get the corners square ? – baxx Oct 31 '21 at 17:54
  • 1
    You can use `capstyle='projecting'`, which extends the line with half of the thickness. This works well when the segments are in angles of 90 degrees. See updated answer. – JohanC Oct 31 '21 at 19:58