2017-08-11 6 views
0

Ich versuche zwei Heatmaps zu zeichnen, die die gleiche x-Achse auf einer einzelnen Figur mit verschiedenen Unterplots haben, deren Skalen unterschiedlich sind, so dass sie unterschiedliche Farbbalken benötigen. Jede Heatmap auch eine unterschiedliche Anzahl von Beobachtungen entlang der y-Achse hat, siehe unten:Wie man die Breite der Farbbalken konsistent in Seaborn heatmap subplots hält

import numpy as np 
import seaborn as sns 

arr1 = np.random.rand(10, 10)*100 
arr2 = np.random.rand(2, 10) 

fig, axes = plt.subplots(2, 1, 
        gridspec_kw={'height_ratios':[5, 1]}, 
        sharex=True) 

sns.heatmap(arr1, ax=axes[0]) 
sns.heatmap(arr2, ax=axes[1]) 

enter image description here

Die Breite der Farbbalken zwischen den Stellplätzen nicht konsistent. Das macht Sinn und ist nicht unerwartet, aber ich möchte die Weite von jedem aus ästhetischen Gründen konsequent machen.

Ich versuchte, die cbar Parameter verwendet und explizit die Größe und Lage des colorbar definieren:

fig, axes = plt.subplots(2, 1, 
        gridspec_kw={'height_ratios':[5, 1]}, 
        sharex=True) 
sns.heatmap(arr1, ax=axes[0]) 

cbar_ax = fig.add_axes([.85, .135, .019, .15]) 
sns.heatmap(arr2, ax=axes[1], cbar_ax=cbar_ax) 

enter image description here

Obwohl in diesem Tun der Grundstücke sind nicht mehr konsistent Breite. Ist hier der beste Ansatz, um Achsen für jeden Farbbalken auf den einzelnen Achsenunterplots zu definieren? Es scheint, es kann ein einfacher Weg sein, die ich

Antwort

3

Lösung zuerst

Wenn möglich am fehlt, versuchen Sie es mit GridSpec Ihre 4 Nebenhandlungen zu organisieren (zwei Plots und zwei Farbbalken in ihrem eigenen axes):

import matplotlib.pyplot as plt 
import numpy as np 
import seaborn as sns 

arr1 = np.random.rand(10, 10)*100 
arr2 = np.random.rand(2, 10) 

fig, axes = plt.subplots(2, 2, 
         gridspec_kw={'height_ratios': [5, 1], 
             'width_ratios': [30, 1], 
             'wspace': 0.1}, 
         sharex='col') 

sns.heatmap(arr1, ax=axes[0][0], cbar_ax=axes[0][1]) 
sns.heatmap(arr2, ax=axes[1][0], cbar_ax=axes[1][1]) 

enter image description here

Dann einige Kommentare auf Ihre Ideen:

Wenn Sie add_axes verwenden, fügen Sie manuell ein Unterplot (axes) hinzu und erzwingen es an einer bestimmten Stelle. Dies kann es für den neuen Teilplan schwierig machen, sich mit anderen Teilplots zu koordinieren. In Ihrer zweiten Handlung stellt sich heraus, dass die 3. axes herumschwebt und auf anderen Teilplots sitzt.

Das Problem mit Ihrem zweiten Ansatz ist, dass Sie die Farbleiste aus dem axes von arr2 verschieben. Daher nimmt das Hauptplot die volle Breite seines axes, während das Hauptplot arr1 die volle Breite seines axes mit seiner Farbleiste teilt. Dachte die beiden Hauptplots scheinen "nicht mehr konsistente Breite" zu sein, die beiden Teilplots (axes sind immer noch konsistent in der Breite).

1

Sie können die Farbbalkenachsen (cbar_ax) als Teil des Subplot-Rasters definieren, sodass alle Abstände und die Breite zwischen den beiden Zeilen synchronisiert sind.

import matplotlib.pyplot as plt 
import numpy as np 
import seaborn as sns 

arr1 = np.random.rand(10, 10)*100 
arr2 = np.random.rand(2, 10) 

fig, axes = plt.subplots(2, 2, 
        gridspec_kw={'height_ratios':[5, 1], 
            'width_ratios' :[1, 0.04]}) 

sns.heatmap(arr1, ax=axes[0,0], cbar_ax=axes[0,1]) 
sns.heatmap(arr2, ax=axes[1,0], cbar_ax=axes[1,1]) 


plt.show() 

enter image description here