如何为单图matplotlib生成多个图例

问题描述

我正在绘制f(x,y,z)的图,并希望将此图显示在2D平面中。为了避免使我的图例混乱,我决定为y使用不同的线型,为z选择不同的颜色,然后将两者放置在两个单独的图例中。即使经过大量的挖掘,我仍然找不到解决方法,所以我要在这里发布我想出的解决方案:)如果有人有更优雅的解决方案,我会不厌其烦:)

解决方法

基本上,解决方案是制作三个图,将其中两个设置为大小(0,0),然后将两个放置在我想要的图例的位置。感觉这很丑陋,但是它给出了一个不错的情节,而我没有找到其他方法:)生成的情节看起来像这样: Pretty plot

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,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])
ax[1].set_axis_off()
ax[2].set_position([box0.x0 + box0.width,box0.y0 + box0.height - 0.25,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]',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')