2017-11-11 3 views
0

Ich bin verloren in verschiedenen Methoden in Matplotlib verwendet.Scatter Plot mit Colorbar und datetime Achse Ticks

Ich möchte ein farbkodiertes Streudiagramm mit einer Farbleiste auf der Seite und Datum auf der X-Achse erstellen.

Aber abhängig davon, wie ich meine ax definiere, erhalte ich verschiedene Fehler. Unten ist der Kern meines Code:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 
import matplotlib.cm as cm 
import matplotlib.dates as mdates 

#.....loading files etc. 

norm = mcolors.Normalize(vmin=0,vmax=1000) 
timerange = pd.date_range(start='2015-01-01', end='2016-01-01', freq='30D') 

### PLOTTING 
fig = plt.figure(figsize=(6.,5)) 
ax = fig.add_subplot(111) 

for Af in Afiles: 
    for index, row in Af.iterrows(): 
     time = pd.to_datetime(row['date'], format="%Y-%m-%d") 
     plt.scatter(time, row['A'], c=row['z'], norm=norm, cmap=colormap,edgecolor='k', lw=0.8, s=80) 

plt.xticks(timerange, rotation=90) 
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d/%m/%Y")) 
plt.xlabel('Time', fontsize=11, color='k') 

clb = fig.colorbar(ax)  
clb.ax.set_title('Value', y=-0.125, fontsize=11) 
clb.ax.invert_yaxis() 

fig.tight_layout() 

dies erzeugt AttributeError: 'AxesSubplot' object has no attribute 'autoscale_None'

aber wenn ich meine angeben ax als das Streudiagramm, so dass ich meine Farbcodierung zum Laufen bringen kann, dann habe ich Probleme mit der Achsenformatierer. Schreiben statt ax = plt.scatter generiert AttributeError: 'PathCollection' object has no attribute 'xaxis'.

Wie kann ich sowohl die Farbbalken UND formatierte Achse Ticks haben?

Antwort

1

Sie die Streuung nicht nennen ax. (Dies überschreibt die bestehenden Achsen ax.)
Die Farbleiste erwartet als erstes Argument eine SkalarMappable (wie z. B. die Streuung). Da die Streuungen alle normalisiert sind, können Sie es aus der Schleife verwenden,

norm = plt.Normalize(...) 
for bla in blubb: 
    scatter = plt.scatter(..., norm=norm) 

Dann

clb = fig.colorbar(scatter) 

Der Rest gleich bleiben sollte.

+0

Natürlich! Dumm ich, danke. Das ist peinlich. – durbachit

0

Die Grundidee ist, dass Sie eine zusätzliche Achse für die Farbleiste hinzufügen müssen.

Es ist schwer zu wissen, ob dies eine exakte Übereinstimmung ist, da Sie kein funktionierendes Beispiel mit Daten geliefert haben. Aber das könnte zumindest als Vorlage dienen.

Zunächst einige Beispieldaten:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 
import matplotlib.cm as cm 
import matplotlib.dates as mdates 
from mpl_toolkits.axes_grid1 import make_axes_locatable 

vmin = 0 
vmax = 1000 
timerange = pd.date_range(start='2015-01-01', end='2016-01-01', freq='30D') 
N = len(timerange) 

data = np.random.randint(vmin, vmax, size=N) 
# z contains the colorbar values for each point 
cmap = plt.get_cmap('Reds') 
z = [cmap((x-vmin)/(vmax-vmin))[:3] for x in data] 
df = pd.DataFrame({"value":data, "datetime":timerange, "z":z}) 

Jetzt Grundstück:

fig = plt.figure(figsize=(6.,5)) 
ax = fig.add_subplot(111) 

plt.scatter(x=df.datetime.values, y=df.value.values, c=df.z) 

ax.set_xticklabels(timerange, rotation=90) 
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d/%m/%Y")) 
ax.set_xlabel('Time') 

Jetzt colorbar hinzufügen:

norm = mcolors.Normalize(vmin=vmin,vmax=vmax) 
m = cm.ScalarMappable(cmap='Reds', norm=norm) 
m.set_array([(x-vmin)/(vmax-vmin) for x in df.value.values]) 

divider = make_axes_locatable(ax) 
cax = divider.append_axes("right", size="5%", pad=0.1) 
clb = plt.colorbar(m, cax=cax) 

scatter plus colormap

+0

Sorry, also zur Klärung, wie würde das für meine Schleife funktionieren? Wie setze ich die Skalarabbildung, wenn ich nicht einen einzigen Datenrahmen habe, aber viele? Ich brauche eine gemeinsame Farbleiste (gemeinsames Farbschema) für viele Datenrahmen mit vielen verschiedenen Wertebereichen. Beachten Sie, dass mein Code für die Farbleiste (bei Einstellung von "ax = plt.scatter") einwandfrei funktionierte, solange ich die numerische x-Achse beibehalten konnte. Das Problem tauchte auf, als ich anfing, mit der Achsenformatierung zu spielen. – durbachit

+0

Wenn Sie eine gemeinsame Farbleiste benötigen, haben Sie nicht viele verschiedene Bereiche in Bezug auf die Farbleiste, Sie haben nur eine. Wählen Sie die Mindest- und Höchstwerte Ihres vollständigen Datasets aus, um die Zuordnung festzulegen. Die Schleife kann gleich bleiben, ich habe nur Beispieldaten für einen Datenrahmen gemacht, um ein funktionierendes Beispiel zu geben. –

+1

Nachdem das gesagt wurde, sieht es so aus, als ob die Antwort von ImportanceOfBeingErnest einfacher ist, und ich werde der Erste sein, der zugibt, dass ich keinen guten Sinn für Eleganz habe, wenn es um Matplotlib geht. Versuchen Sie es einmal! –