1

我正在绘制 f(x,y,z) 的图,并希望将其显示在 2D 平面中。为了避免弄乱我的图例,我决定为 y 设置不同的线条样式,为 z 设置不同的颜色,并将两者放在两个单独的图例中。即使经过大量挖掘,我也无法找到如何做到这一点,所以我在这里发布了我想出的解决方案 :) 如果有人有更优雅的解决方案,我会全神贯注 :)

4

1 回答 1

2

基本上解决方案是制作三个图,将其中两个设置为大小(0,0)并将这两个放置在我想要图例的位置。这感觉像是一种丑陋的方式,但它给出了一个很好的情节,我没有找到任何其他方式:) 结果情节如下所示: 漂亮的情节

def plot_alt(style = 'log'):

cmap = cm.get_cmap('inferno')
color_scale = 1.2 #Variable to get colors from a certain part of the colormap

#Making grids for delta T and average concentration
D_T_axis = -np.logspace(np.log10(400), np.log10(1), 7)
C_bar_list = np.linspace(5,10,4)

ST_list = np.logspace(-3,-1,100)

# f(x,y,z)
DC_func = lambda C_bar, ST, DT: 2*C_bar * (1 - np.exp(ST*DT))/(1 + np.exp(ST*DT))

#Some different linestyles
styles = ['-', '--', '-.', ':']

fig, ax = plt.subplots(1,3, figsize = (10,5))

plt.sca(ax[0])
for i, C_bar in enumerate(C_bar_list): #See plot_c_rel_av_DT() for 'enumerate'
    for j, DT in enumerate(D_T_axis):
        plt.plot(ST_list, DC_func(C_bar, ST_list, DT), color = cmap(np.log10(-DT)/(color_scale*np.log10(-D_T_axis[0]))),
                                   linestyle = styles[i])

# Generating separate legends by plotting lines in the two other subplots
# Basically: to get two separate legends i make two plots, place them where i want the legends
# and set their size to zero, then display their legends.
plt.sca(ax[1]) #Set current axes to ax[1]
for i, C_bar in enumerate(C_bar_list):
    # Plotting the different linestyles
    plt.plot(C_bar_list, linestyle = styles[i], color = 'black', label = str(round(C_bar, 2)))
plt.sca(ax[2])
for DT in D_T_axis:
    #plotting the different colors
    plt.plot(D_T_axis, color = cmap(np.log10(-DT)/(color_scale*np.log10(-D_T_axis[0]))), label = str(int(-DT)))

#Placing legend
#This is where i move and scale the three plots to make one plot and two legends
box0 = ax[0].get_position() #box0 is an object that contains the position and dimentions of the ax[0] subplot
box2 = ax[2].get_position()

ax[0].set_position([box0.x0, box0.y0, box2.x0 + 0.4*box2.width, box0.height])
box0 = ax[0].get_position()

ax[1].set_position([box0.x0 + box0.width, box0.y0 + box0.height + 0.015, 0,0])
ax[1].set_axis_off()
ax[2].set_position([box0.x0 + box0.width ,box0.y0 + box0.height - 0.25, 0,0])
ax[2].set_axis_off()

#Displaying plot
plt.sca(ax[0])

plt.xscale('log')
plt.xlim(0.001, 0.1)
plt.ylim(0, 5)

plt.xlabel(r'$S_T$')
plt.ylabel(r'$\Delta C$')
ax[1].legend(title = r'$\langle c \rangle$ [mol/L]',
             bbox_to_anchor = (1,1), loc = 'upper left')
ax[2].legend(title = r'$-\Delta T$ [K]', bbox_to_anchor = (1,1), loc = 'upper left')

#Suptitle is the title of the figure. You can also have titles for the individual subplots
plt.suptitle('Steady state concentration gradient as a function of Soret-coefficient\n'
             'for different temperature gradients and total concentrations')
于 2020-10-24T01:42:16.070 回答