matplotlib.pyplot Легенда цветовой карты для 2D-параметра - PullRequest
0 голосов
/ 25 января 2020

Я строю серию графиков логарифмического смещения по среднему квадрату (MSD) по тем же осям для моделирования самоходных частиц. Моделирование выполняется с различными значениями для переходного стандартного отклонения Dtrans = [0.1, 0.3, 1.0, 3.0, 10] и для стандартного отклонения вращения Drot = [0.1, 0.3, 1.0, 3.0, 10, 30, 100, 300], что дает в общей сложности 5 × 8 = 40 моделирования. Вот что у меня сейчас:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cmx
import itertools

# List of colour maps
cmaps = ['YlOrRd', 'Greens', 'Blues', 'Purples','RdPu']

nparticles = 5
npts=1000
step=1000
dt = 0.0001

Drot = [0.1, 0.3, 1.0, 3.0, 10, 30, 100, 300]
Dtrans = [0.1, 0.3, 1.0, 3.0, 10]

plt.figure()
plt.title('MSD against time')
plt.xlabel('Time')
plt.ylabel('MSD')

# Time steps along horizontal axis:
timeval = np.linspace(0,dt*step*(npts-1),npts)

# For each value of Dtrans
for d1 in range(len(Dtrans)):

    # Choose a colour map:
    colourmap = plt.get_cmap(cmaps[d1])
    # Limit it to the middle 60%
    colourmap = colors.ListedColormap(colourmap(np.linspace(0.2, 0.8, 256)))

    # Get a colour from the map for each value of Drot:
    values = range(len(Drot))
    cNorm = colors.Normalize(vmin=0,vmax=values[-1])
    scalarMap=cmx.ScalarMappable(norm=cNorm,cmap=colourmap)

    for d2 in range(len(Drot)):
        Dr = Drot[d2]
        Dt = Dtrans[d1]
        MSD = np.zeros((npts,))

        x = np.zeros((npts,nparticles))
        y = np.zeros((npts,nparticles))
        for k in range(npts):
            data0=np.loadtxt(open("./Lowdensity/Drot_"+str(Dr)+"/Dtrans_"+str(Dt)+"/ParticleData/ParticleData"+str(k*step)+".csv",'rb'),delimiter=',')
            x0,y0= data0[:nparticles,1],data0[:nparticles,2]
            x[k,:]=x0
            y[k,:]=y0

        for k in range(npts):
            MSD[k] = np.mean(np.mean((x[k:npts,:] - x[0:(npts-k),:])**2 + (y[k:npts,:] - y[0:(npts-k),:])**2,axis=0))

        colorVal = scalarMap.to_rgba(values[d2])

        plt.loglog(timeval,MSD,color=colorVal)
        plt.legend([('Dtrans='+str(i)+', Drot='+str(j)) for [i,j] in np.array(list(itertools.product(Dtrans,Drot)))])

#plt.loglog(timeval, MSDthry(timeval, 0.5, 100, 70, dt*step*npts))
plt.show()

log-log plot of MSD against time with nasty legend

Цветовые карты работают прекрасно, но моя нынешняя легенда действительно ужасна и не вписывается в сюжет. В идеале я хочу, чтобы легенда состояла из пяти цветных полос, расположенных вертикально, со значениями Dtrans вдоль вертикальной оси и значениями Drot по горизонтали. Как я могу это реализовать? Спасибо!

Ответы [ 2 ]

1 голос
/ 25 января 2020

Может быть, таблица может сделать работу:

#initialyze an array at the beginning 
colorsarray = np.empty([5,5] )
for d1 in range(len(Dtrans)):
    ...     
    colorVal = scalarMap.to_rgba(values[d2]) 
    colorsarray[d1, d2] =colorVal

    plt.loglog(timeval,MSD,color=colorVal) 


tab=plt.table(cellText="" , colLabels=Dtrans, 
    rowLabels=Drot, colWidths = [0.2,0.2], 
    loc='higher left', cellColours=colorsarray )
plt.show()
0 голосов
/ 27 января 2020

Я решил это сам, но для полноты вот мое решение.

Как и в решении Рено, я инициализирую матрицу для цветов, но помещаю их в тепловую карту, а не в таблицу. Я использую plt.subplot для построения тепловой карты рядом с графиком.

colorsarray = np.empty((len(Dtrans),len(Drot)),dtype=(float,4))

fig=plt.figure()
gs=fig.add_gridspec(3,3)

ax1 = fig.add_subplot(gs[:,:-1])
ax2 = fig.add_subplot(gs[1,2])

for d1 in range(len(Dtrans)):
    ...
    colorVal = scalarMap.to_rgba(values[d2])
    colorsarray[d1, d2] = colorVal

    ax1.loglog(timeval,MSD,color=colorVal)

plt.setp(ax2.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
ax2.imshow(colorsarray,interpolation=None)
ax2.set_xticks(np.arange(len(Drot)))
ax2.set_yticks(np.arange(len(Dtrans)))
ax2.set_xticklabels(Drot)
ax2.set_yticklabels(Dtrans)
ax2.set_xlabel('D_rot')
ax2.set_ylabel('D_trans')
ax2.axis('equal')

plt.tight_layout()
plt.show()

Я использовал эту статью о тепловых картах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...