Based on the matplotlib example code I constructed a 3D version of a multicolored line. I am working in a jupyter notebook and by using %matplotlib notebook
I may zoom into the plot and the corner edges are rendered smoothly in my browser - perfect! However, when I export the plot as png or pdf file for further usage the corner edges are "jagged".
Any ideas how to smoothen the 3D-multicolored line?
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')
I think join style is what controls the look of segment joints. Line3DCollection
does have a set_joinstyle()
function, but that doesn't seem to make any difference. So I've to abandon Line3DCollection
and plot the line segment by segment, and for each segment, call its set_solid_capstyle('round')
.
Below is what works for me:
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')
Output image at zoom:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With