2017-06-23 4 views
1

Ich habe eine problematische Subplot, die zwei Datenskalen hat. Anstatt eine Log-Skala zu verwenden, mag ich die Achse brechen, so dass die Hälfte der Achse subplot y von 0 bis 10 läuft und die andere Hälfte von 10 bis 100.matplotlib create broken axis im Unterplot

import numpy as np 
import matplotlib.pyplot as plt 
x = np.random.uniform(0, 10, 40) 
y = np.concatenate([np.random.uniform(0, 1, 30), np.random.uniform(0, 100, 10)]) 
y2 = np.random.uniform(0, 1, 40) 
fig, ax = plt.subplots(2, sharex=True) 
ax[0].scatter(x, y) # problematic subplot 
ax[1].scatter(x, y2) 
plt.show() 

enter image description here

Ich habe versucht, nach pyplots Axis-Demo, obwohl das falsch scheint. Muss ich insgesamt vier Unterplots erstellen, um dies zu tun? Dies ist nur ein Dummy-Beispiel, mein wirkliches Problem hat mehrere Unterplots, von denen viele diese gebrochene Achse benötigen.

import numpy as np 
import matplotlib.pyplot as plt 
x = np.random.uniform(0, 10, 40) 
y = np.concatenate([np.random.uniform(0, 1, 30), np.random.uniform(0, 100, 10)]) 
y2 = np.random.uniform(0, 1, 40) 

fig, ax = plt.subplots(4, sharex=True) 

# Create broken axis with first two subplots 
ax[0].scatter(x, y) 
ax[1].scatter(x, y) 
ax[0].set_ylim(1, 100) 
ax[1].set_ylim(0, 1) 
ax[0].spines['bottom'].set_visible(False) 
ax[1].spines['top'].set_visible(False) 

# From https://matplotlib.org/examples/pylab_examples/broken_axis.html 
d = .015 # how big to make the diagonal lines in axes coordinates 
# arguments to pass to plot, just so we don't keep repeating them 
kwargs = dict(transform=ax[0].transAxes, color='k', clip_on=False) 
ax[0].plot((-d, +d), (-d, +d), **kwargs)  # top-left diagonal 
ax[0].plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal 

kwargs.update(transform=ax[1].transAxes) # switch to the bottom axes 
ax[0].plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal 
ax[0].plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal 



# Try my best to fix bottom two plots so they look like one plot 
ax[2].scatter(x, y2) 
ax[3].scatter(x, y2) 
ax[2].set_ylim(.5, 1.0) 
ax[3].set_ylim(0, .5) 
ax[2].spines['bottom'].set_visible(False) 
ax[3].spines['top'].set_visible(False) 
plt.savefig('ex.pdf') 

enter image description here

+0

Es ist nicht wirklich klar, ob Sie die obere Kurve als gebrochene Achsen oder beiden Plots als gebrochene Achsen wollen. Können Sie beschreiben, was genau Sie erreichen möchten und was Ihre aktuelle Handlung "hässlich" macht? – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest Ich möchte nur, dass die oberste Handlung unterbrochen wird. Im unteren Teilplotter sollte die Achse kontinuierlich sein, nicht zwei 0,5 Punkte haben. – kilojoules

Antwort

1

Ich könnte nur zwei Handlungsstränge zu verwenden, legen nahe, eine oben und eine unten. Dann teilen Sie die obere in zwei über mpl_toolkits.axes_grid1.make_axes_locatable.

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


x = np.random.uniform(0, 10, 40) 
y = np.concatenate([np.random.uniform(0, 1, 30), np.random.uniform(0, 100, 10)]) 
y2 = np.random.uniform(0, 1, 40) 

fig, axes = plt.subplots(nrows=2, sharex=True) 

ax = axes[0] 
divider = make_axes_locatable(ax) 
ax2 = divider.new_vertical(size="100%", pad=0.1) 
fig.add_axes(ax2) 

ax.scatter(x, y) 
ax.set_ylim(0, 1) 
ax.spines['top'].set_visible(False) 
ax2.scatter(x, y) 
ax2.set_ylim(10, 100) 
ax2.tick_params(bottom="off", labelbottom='off') 
ax2.spines['bottom'].set_visible(False) 


# From https://matplotlib.org/examples/pylab_examples/broken_axis.html 
d = .015 # how big to make the diagonal lines in axes coordinates 
# arguments to pass to plot, just so we don't keep repeating them 
kwargs = dict(transform=ax2.transAxes, color='k', clip_on=False) 
ax2.plot((-d, +d), (-d, +d), **kwargs)  # top-left diagonal 
ax2.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal 

kwargs.update(transform=ax.transAxes) # switch to the bottom axes 
ax.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal 
ax.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal 


#create bottom subplot as usual 
axes[1].scatter(x, y2) 


plt.show() 

enter image description here