2 votes

matplotlib : sous-plots de même taille ?

J'ai des difficultés avec matplotlib en Python pour créer deux graphiques côte à côte. J'ai réussi à les faire rester l'un à côté de l'autre, mais j'ai besoin qu'ils aient exactement la même taille : chaque point du graphique de droite doit pouvoir être facilement mis en correspondance avec un emplacement du graphique de gauche à l'œil nu. Au lieu de cela, le graphique de droite (qui est un diagramme de dispersion) présente des marges qui le font paraître légèrement plus petit que le graphique de gauche (une carte thermique).

enter image description here

La façon dont je génère la carte thermique est la suivante :

def plot_map(matrix):
    # Plot it out
    #fig, ax = plt.subplots()
    fig = plt.figure()
    ax = plt.subplot(1,2,1)
    c = m.colors.ColorConverter().to_rgb
    cm = make_colormap([(0,1,0), (1,1,0), 0.1, (1,1,0), (1,0.5,0), 0.66, (1,0.5,0),(1,0,0)]) 
    heatmap = ax.pcolor(matrix, cmap=cm)

    # Format
    fig = plt.gcf()
    fig.set_size_inches(20, 20)
    plt.gca().set_aspect('equal')
    # turn off the frame
    ax.set_frame_on(False)

    # put the major ticks at the middle of each cell
    ax.set_yticks(np.arange(matrix.shape[0]) + 0.5, minor=False)
    ax.set_xticks(np.arange(matrix.shape[1]) + 0.5, minor=False)

    # want a more natural, table-like display
    ax.invert_yaxis()
    ax.xaxis.tick_top()

    # note I could have used matrix.columns but made "labels" instead
    ax.set_xticklabels(range(0,matrix.shape[0]), minor=False)
    ax.set_yticklabels(range(0,matrix.shape[1]), minor=False)
    ax.grid(False)

    # Turn off all the ticks
    ax = plt.gca()

    for t in ax.xaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    for t in ax.yaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False

    divider = make_axes_locatable(ax)       
    cax = divider.append_axes("right", size="5%", pad=0.05)
    plt.colorbar(heatmap,cax=cax)

    return (fig,ax)

Ensuite, l'axe est transmis à une autre fonction pour tracer les petites lignes bleues sur la carte :

def plot_chosen(edges,endnodes,side,ax):
    for e in edges:
        u = endnodes[e - 1][0]
        v = endnodes[e - 1][1]
        xu, yu = get_center(u,side)
        xv, yv = get_center(v,side)
        ax.plot([xu+0.5, xv+0.5], [yu+0.5, yv+0.5], 'k-', lw=4, color='blue',alpha=0.5)

Enfin, je trace la courbe de dispersion comme suit

def plot_satter(edges,endnodes,side,xs,ys,data):
    plt.margins(0)
    ax = plt.subplot(1, 2, 2)
        # Format
    fig = plt.gcf()
    fig.set_size_inches(20, 20)
    plt.gca().set_aspect('equal')
    # turn off the frame
    ax.set_frame_on(False)

    # put the major ticks at the middle of each cell
    ax.set_yticks(np.arange(side) + 0.5, minor=False)
    ax.set_xticks(np.arange(side) + 0.5, minor=False)

    # want a more natural, table-like display
    ax.invert_yaxis()
    ax.xaxis.tick_top()

    ax.set_xmargin(0)
    ax.set_ymargin(0)

    # note I could have used matrix.columns but made "labels" instead
    ax.set_xticklabels(range(0,side), minor=False)
    ax.set_yticklabels(range(0,side), minor=False)
    ax.grid(False)

    # Turn off all the ticks
    ax = plt.gca()

    for t in ax.xaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    for t in ax.yaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    cm = make_colormap([(0,0,1), (0,1,1), 0.1, (0,1,1), (1,1,0), 0.66, (1,1,0),(1,0,0)]) 
    resmap = plt.scatter(xs,ys, c=data,cmap=cm,edgecolors='none',alpha=0.5,s=data)
    divider = make_axes_locatable(ax)       
    cax = divider.append_axes("right", size="5%", pad=0.05)
    plt.colorbar(resmap,cax=cax)

Mais je ne trouve aucun moyen de rendre le nuage de points aussi grand que la carte thermique. En fait, il est censé être aussi grand que sa barre de couleur, mais cela ne fonctionne pas non plus... Si cela me fait penser qu'il y a une certaine marge autour du nuage de points....

Par ailleurs, existe-t-il un moyen de rendre le fichier PNG moins carré ? Pourrait-il s'agir d'un rectangle ?

Merci !

3voto

ImportanceOfBeingErnest Points 119438

Pour obtenir de l'aide, vous devez fournir un exemple minimal de travail . Vous découvrirez que la production d'un tel exemple minimal de travail , presque toujours vous fait trouver vous-même le problème et la solution correspondante.
Aussi, structurez votre code !

Comme nous n'avons pas la connaissance nécessaire de vos données et des variables que vous utilisez, il est presque impossible de trouver une solution.

Ce que vous devez faire, c'est décomposer le problème. Vous cherchez la différence entre deux choses, alors faites en sorte qu'elles soient aussi égales que possible. Si vous appliquez tout aux deux parcelles simultanément, comment peuvent-elles être différentes après tout ?

Le code suivant montre comment faire et il ne montre pas de différence de taille entre les deux graphiques. Commencez donc à partir de là et ajoutez les éléments dont vous pourriez avoir besoin en conséquence. Une étape à la fois, jusqu'à ce que vous trouviez le morceau de code qui pose problème.

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable

x = np.linspace(0,100,101)
X, Y = np.meshgrid(x,x)
data = np.sin(X/2.3)*np.cos(Y/2.7)*np.cos(X*Y/20.)

fig = plt.figure(figsize=(10,5))
ax1=fig.add_subplot(121)
ax2=fig.add_subplot(122)
plt.subplots_adjust(wspace = 0.33 )

heatmap = ax1.pcolor(data, cmap="RdPu")
resmap =  ax2.scatter(X,Y, c=data, cmap="YlGnBu",edgecolors='none',alpha=0.5)

for ax in [ax1,ax2]:
    ax.set_frame_on(False)

    ax.set_aspect('equal')

    ax.invert_yaxis()
    ax.xaxis.tick_top()

    ax.set_xmargin(0)
    ax.set_ymargin(0)

    ax.grid(False)

    for t in ax.xaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    for t in ax.yaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False

    ax.set_xlim([x[0],x[-1]])
    ax.set_ylim([x[0],x[-1]])

divider1 = make_axes_locatable(ax1)       
cax1 = divider1.append_axes("right", size="5%", pad=0.05)
plt.colorbar(heatmap,cax=cax1)

divider2 = make_axes_locatable(ax2)       
cax2 = divider2.append_axes("right", size="5%", pad=0.05)
plt.colorbar(resmap,cax=cax2)

plt.show()

Et à propos, fig = plt.figure(figsize=(10,5)) produit un rectangle, tandis que fig = plt.figure(figsize=(20,20)) produit un carré.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X