简体   繁体   中英

Python: How do I make a plot with variable line thickness that changes gradually?

I have the following code, which makes a plot of variable line thickness:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
x = np.array(range(6))
y = [10, 15,10, 8, 13, 20]
widths = [1, 5,3, 8, 1, 2]
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, linewidths=widths,color='blue')
fig,a = plt.subplots()
a.add_collection(lc)
a.set_xlim(0,7)
a.set_ylim(0,25)
fig.show()

I would like to smooth the transitions between the line thicknesses so that the changes are gradual and look nice. I'm currently using Matplotlib but it doesn't have to be (would use Seaborn, etc. if that works). Does anyone know how to do this?

Another option would be to use Polygons instead of line segments. Unfortunately, I don't know how to translate the width (in points ) of a line segment to Data coordinates . Here I've manually adjusted the widths to try and match the desired result.

fig, ax = plt.subplots()
ax.set_xlim((0,5))
ax.set_ylim((0,25))

new_w = np.array(widths)/5. # <<< change according to your needs
# FIXME: this should probably be done using some sort of affine
#        transformation already build-in in matplotlib, but I don't know how

for i in range(len(x)-1):
    c = [[x[i], y[i]+new_w[i]/2.],
         [x[i+1], y[i+1]+new_w[i+1]/2.],
         [x[i+1], y[i+1]-new_w[i+1]/2.],
         [x[i], y[i]-new_w[i]/2.]
        ]
    p = matplotlib.patches.Polygon(c)
    ax.add_patch(p)

plt.show()

在此处输入图片说明

One solution, which is not perfect, would be to dissect each of your line segments in small chunks and interpolate the width of the segments. It works pretty well, except at the angles between two line segments, but it's a start:

new_x = np.linspace(x[0],x[-1],100*len(x)) # new_x has 100x more points than x
new_y = np.interp(new_x,x,y)
new_w = np.interp(new_x,x,widths)

points = np.array([new_x, new_y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, linewidths=new_w,color='blue')
fig,a = plt.subplots()
a.add_collection(lc)
a.set_xlim(0,7)
a.set_ylim(0,25)
fig.show()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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