matplotlib Line3DCollection多色线边缘呈“锯齿状”

qyyhg6bp  于 2023-05-01  发布在  其他
关注(0)|答案(2)|浏览(127)

基于matplotlib example code,我构建了一条多色线的3D版本。我在一个Jupyter笔记本上工作,通过使用X1 M0 N1 X,我可以放大情节,角落边缘在我的浏览器中平滑渲染-完美!然而,当我将绘图导出为PNG或PDF文件以供进一步使用时,角边是“锯齿状”的。
有什么想法如何平滑3D多色线?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm    
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Line3DCollection
%matplotlib notebook

# Generate random data
np.random.seed(1)
n = 20 # number of data points
#set x,y,z data
x = np.random.uniform(0, 1, n)
y  = np.random.uniform(0, 1, n)
z = np.arange(0,n)

# Create a colormap for red, green and blue and a norm to color
# f' < -0.5 red, f' > 0.5 blue, and the rest green
cmap = ListedColormap(['r', 'g', 'b'])
norm = BoundaryNorm([-1, -0.5, 0.5, 1], cmap.N)

#################
### 3D Figure ###
#################

# Create a set of line segments
points = np.array([x, y, z]).T.reshape(-1, 1, 3)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

# Create the 3D-line collection object
lc = Line3DCollection(segments, cmap=plt.get_cmap('copper'),
                    norm=plt.Normalize(0, n))
lc.set_array(z) 
lc.set_linewidth(2)

#plot
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_zlim(0, max(z))
plt.title('3D-Figure')
ax.add_collection3d(lc, zs=z, zdir='z')

#save plot
plt.savefig('3D_Line.png', dpi=600, facecolor='w', edgecolor='w',
            orientation='portrait')
5jdjgkvh

5jdjgkvh1#

我认为join style是控制分段关节外观的东西。Line3DCollection确实有一个set_joinstyle()函数,但这似乎没有任何区别。所以我必须放弃Line3DCollection,并逐段绘制线段,对于每一段,称其为set_solid_capstyle('round')
下面是对我有用的:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Generate random data
np.random.seed(1)
n = 20 # number of data points
#set x,y,z data
x = np.random.uniform(0, 1, n)
y  = np.random.uniform(0, 1, n)
z = np.arange(0,n)

#################
### 3D Figure ###
#################

# Create a set of line segments
points = np.array([x, y, z]).T.reshape(-1, 1, 3)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

cmap=plt.get_cmap('copper')
colors=[cmap(float(ii)/(n-1)) for ii in range(n-1)]

#plot
fig = plt.figure()
ax = fig.gca(projection='3d')

for ii in range(n-1):
    segii=segments[ii]
    lii,=ax.plot(segii[:,0],segii[:,1],segii[:,2],color=colors[ii],linewidth=2)
    #lii.set_dash_joinstyle('round')
    #lii.set_solid_joinstyle('round')
    lii.set_solid_capstyle('round')

ax.set_zlim(0, max(z))
plt.title('3D-Figure')

#save plot
plt.savefig('3D_Line.png', dpi=600, facecolor='w', edgecolor='w',
            orientation='portrait')

缩放时的输出图像:

wlzqhblo

wlzqhblo2#

基于@Jason的回答,我实际上直接在LineCollection init中使用了capstyle,而不是joinstyle,后者实际上什么也没做。
我的代码片段:

lc = LineCollection(segments, cmap=viridis, norm=norm, joinstyle="round", capstyle="round")

当然,它并不完美,但它在某种程度上减少了问题。

相关问题