Die Antwort von Paulus ist eine sehr gute Methode, dies zu tun.
Wenn Sie jedoch keine benutzerdefinierte Transformation durchführen möchten, können Sie einfach zwei Unterzeichnungen verwenden, um denselben Effekt zu erzielen.
Anstatt ein Beispiel von Grund auf neu zusammenzustellen, gibt es ein hervorragendes Beispiel dafür, das Paul Ivanov in den matplotlib-Beispielen geschrieben hat (Es ist nur im aktuellen Git-Tipp enthalten, da es erst vor einigen Monaten festgelegt wurde. Es ist noch nicht auf der Webseite.) .
Dies ist nur eine einfache Modifikation dieses Beispiels, um eine diskontinuierliche x-Achse anstelle der y-Achse zu haben. (Deshalb mache ich diesen Beitrag zu einem CW)
Grundsätzlich machst du einfach so etwas:
import matplotlib.pylab as plt
import numpy as np
x = np.r_[0:1:0.1, 9:10:0.1]
y = np.sin(x)
fig,(ax,ax2) = plt.subplots(1, 2, sharey=True)
ax.plot(x, y, 'bo')
ax2.plot(x, y, 'bo')
ax.set_xlim(0,1)
ax2.set_xlim(9,10)
ax.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax.yaxis.tick_left()
ax.tick_params(labeltop='off')
ax2.yaxis.tick_right()
plt.subplots_adjust(wspace=0.15)
plt.show()
Um den //
Effekt der unterbrochenen Achsenlinien hinzuzufügen , können wir dies tun (wiederum modifiziert nach Paul Ivanovs Beispiel):
import matplotlib.pylab as plt
import numpy as np
x = np.r_[0:1:0.1, 9:10:0.1]
y = np.sin(x)
fig,(ax,ax2) = plt.subplots(1, 2, sharey=True)
ax.plot(x, y, 'bo')
ax2.plot(x, y, 'bo')
ax.set_xlim(0,1)
ax2.set_xlim(9,10)
ax.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax.yaxis.tick_left()
ax.tick_params(labeltop='off')
ax2.yaxis.tick_right()
plt.subplots_adjust(wspace=0.15)
d = .015
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((1-d,1+d),(-d,+d), **kwargs)
ax.plot((1-d,1+d),(1-d,1+d), **kwargs)
kwargs.update(transform=ax2.transAxes)
ax2.plot((-d,d),(-d,+d), **kwargs)
ax2.plot((-d,d),(1-d,1+d), **kwargs)
plt.show()
//
Effekt zu erzielen, scheint nur dann gut zu funktionieren, wenn das Verhältnis der Teilzahlen 1: 1 beträgt. Wissen Sie, wie Sie es mit einem von zGridSpec(width_ratio=[n,m])
./
unterdrückt der Effekt nicht die normale Zecke, die ästhetischIch sehe viele Vorschläge für diese Funktion, aber keinen Hinweis darauf, dass sie implementiert wurde. Hier ist eine praktikable Lösung für den Moment. Es wendet eine Schrittfunktionstransformation auf die x-Achse an. Es ist eine Menge Code, aber es ist ziemlich einfach, da das meiste davon benutzerdefiniertes Skalierungsmaterial ist. Ich habe keine Grafiken hinzugefügt, um den Ort der Unterbrechung anzuzeigen, da dies eine Frage des Stils ist. Viel Glück beim Beenden des Jobs.
from matplotlib import pyplot as plt from matplotlib import scale as mscale from matplotlib import transforms as mtransforms import numpy as np def CustomScaleFactory(l, u): class CustomScale(mscale.ScaleBase): name = 'custom' def __init__(self, axis, **kwargs): mscale.ScaleBase.__init__(self) self.thresh = None #thresh def get_transform(self): return self.CustomTransform(self.thresh) def set_default_locators_and_formatters(self, axis): pass class CustomTransform(mtransforms.Transform): input_dims = 1 output_dims = 1 is_separable = True lower = l upper = u def __init__(self, thresh): mtransforms.Transform.__init__(self) self.thresh = thresh def transform(self, a): aa = a.copy() aa[a>self.lower] = a[a>self.lower]-(self.upper-self.lower) aa[(a>self.lower)&(a<self.upper)] = self.lower return aa def inverted(self): return CustomScale.InvertedCustomTransform(self.thresh) class InvertedCustomTransform(mtransforms.Transform): input_dims = 1 output_dims = 1 is_separable = True lower = l upper = u def __init__(self, thresh): mtransforms.Transform.__init__(self) self.thresh = thresh def transform(self, a): aa = a.copy() aa[a>self.lower] = a[a>self.lower]+(self.upper-self.lower) return aa def inverted(self): return CustomScale.CustomTransform(self.thresh) return CustomScale mscale.register_scale(CustomScaleFactory(1.12, 8.88)) x = np.concatenate((np.linspace(0,1,10), np.linspace(9,10,10))) xticks = np.concatenate((np.linspace(0,1,6), np.linspace(9,10,6))) y = np.sin(x) plt.plot(x, y, '.') ax = plt.gca() ax.set_xscale('custom') ax.set_xticks(xticks) plt.show()
quelle
def transform
demInvertedCustomTransform
, wo er lesen sollteself.upper
stattupper
. Vielen Dank für das großartige Beispiel!transform_non_affine
statttransform
. Siehe meinen Patch unter stackoverflow.com/a/34582476/1214547 .Überprüfen Sie das Paket mit den defekten Achsen :
import matplotlib.pyplot as plt from brokenaxes import brokenaxes import numpy as np fig = plt.figure(figsize=(5,2)) bax = brokenaxes(xlims=((0, .1), (.4, .7)), ylims=((-1, .7), (.79, 1)), hspace=.05) x = np.linspace(0, 1, 100) bax.plot(x, np.sin(10 * x), label='sin') bax.plot(x, np.cos(10 * x), label='cos') bax.legend(loc=3) bax.set_xlabel('time') bax.set_ylabel('value')
quelle
from brokenaxes import brokenaxes
nach der Installation nicht in Pycharm Community 2016.3.2 verwendet werden. @ ben.dichterpip install brokenaxes==0.2
, um eine feste Version des Codes zu installieren.Bei der Beantwortung der Frage von Frederick Nord, wie die parallele Ausrichtung der diagonalen "Bruchlinien" bei Verwendung einer Gitterspezifikation mit einem Verhältnis von 1: 1 ungleich sein kann, können die folgenden Änderungen auf der Grundlage der Vorschläge von Paul Ivanov und Joe Kingtons hilfreich sein. Das Breitenverhältnis kann unter Verwendung der Variablen n und m variiert werden.
import matplotlib.pylab as plt import numpy as np import matplotlib.gridspec as gridspec x = np.r_[0:1:0.1, 9:10:0.1] y = np.sin(x) n = 5; m = 1; gs = gridspec.GridSpec(1,2, width_ratios = [n,m]) plt.figure(figsize=(10,8)) ax = plt.subplot(gs[0,0]) ax2 = plt.subplot(gs[0,1], sharey = ax) plt.setp(ax2.get_yticklabels(), visible=False) plt.subplots_adjust(wspace = 0.1) ax.plot(x, y, 'bo') ax2.plot(x, y, 'bo') ax.set_xlim(0,1) ax2.set_xlim(10,8) # hide the spines between ax and ax2 ax.spines['right'].set_visible(False) ax2.spines['left'].set_visible(False) ax.yaxis.tick_left() ax.tick_params(labeltop='off') # don't put tick labels at the top ax2.yaxis.tick_right() d = .015 # how big to make the diagonal lines in axes coordinates # arguments to pass plot, just so we don't keep repeating them kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) on = (n+m)/n; om = (n+m)/m; ax.plot((1-d*on,1+d*on),(-d,d), **kwargs) # bottom-left diagonal ax.plot((1-d*on,1+d*on),(1-d,1+d), **kwargs) # top-left diagonal kwargs.update(transform=ax2.transAxes) # switch to the bottom axes ax2.plot((-d*om,d*om),(-d,d), **kwargs) # bottom-right diagonal ax2.plot((-d*om,d*om),(1-d,1+d), **kwargs) # top-right diagonal plt.show()
quelle
Für Interessenten habe ich die Antwort von @ Paul erweitert und zum ProPlot-Matplotlib-Paket hinzugefügt . Es kann "Sprünge", "Beschleunigungen" und "Verlangsamungen" der Achse ausführen .
Derzeit gibt es keine Möglichkeit, "Kreuze" hinzuzufügen, die den diskreten Sprung wie in Joes Antwort anzeigen, aber ich plane, dies in Zukunft hinzuzufügen. Ich plane auch, einen Standard-Tick-Locator hinzuzufügen, der abhängig von den
CutoffScale
Argumenten sinnvolle Standard-Tick-Positionen festlegt .quelle