Mpld3: ENH: twinx/twiny funktioniert nicht.

Erstellt am 7. Mai 2014  ·  17Kommentare  ·  Quelle: mpld3/mpld3

twinx/twiny funktionieren nicht wie erwartet. Ich weiß, dass dies auf der TODO-Liste steht, aber es gibt noch kein offenes Problem dafür.

Es scheint, dass nur der letzte Datensatz geplottet wird. Hier ist das offizielle Beispiel.

mpld3 gibt zurück:
image

tk-agg gibt zurück:
image

Code zum reproduzieren

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import mpld3
mpld3.enable_notebook()

fig, ax1 = plt.subplots()
t = np.arange(0.01, 10.0, 0.01)
s1 = np.exp(t)
ax1.plot(t, s1, 'b-')
ax1.set_xlabel('time (s)')
# Make the y-axis label and tick labels match the line color.
ax1.set_ylabel('exp', color='b')
for tl in ax1.get_yticklabels():
    tl.set_color('b')


ax2 = ax1.twinx()
s2 = np.sin(2*np.pi*t)
ax2.plot(t, s2, 'r.')
ax2.set_ylabel('sin', color='r')
for tl in ax2.get_yticklabels():
    tl.set_color('r')
plt.show()

Hilfreichster Kommentar

Ich habe das Problem vermieden, indem ich ein Alpha auf den Hintergrund der zweiten Achse gesetzt habe.

ax2.patch.set_alpha(0.0)

Alle 17 Kommentare

PS unter Features kann der letzte Aufzählungspunkt "zusätzliche Interaktivitätstools wie Brushing und Box-Zoom" wahrscheinlich gestrichen werden, da Box-Zoom und Brusing beide implementiert sind.

Danke - ich kann mir vorstellen, dass dies noch eine ganze Weile ein offenes Problem sein wird ... es zu beheben würde einige sehr grundlegende Änderungen am Paket erfordern.

Aus Neugier: liegt das Problem in d3.js, mplexporter oder mpld3?

Könnte vielleicht eine Warnung hinzugefügt werden? (Twinx x noch nicht implementiert)

Hmm, oder noch besser, da die Frame-Ticks auf der rechten Seite abgeholt werden, könnte ich dies vielleicht vortäuschen, indem ich eine skalierte blaue Linie auf der ersten (linken Achse) zeichne. Werde es morgen versuchen...

Eine Warnung wäre eine gute Idee. Es sollte in mplexporter/exporter.py passieren. Ich bin mir nicht sicher, wie ich dies am besten im Axes-Objekt erkennen kann. Der erste Schritt, um herauszufinden, wie dies implementiert werden kann, besteht wahrscheinlich darin, herauszufinden, wie eine Warnung ausgegeben wird, wenn sie vorhanden ist!

twinx() und twiny() führen zur Erstellung einer zusätzlichen Achse, die die gleiche Position wie die ursprünglichen Achsen hat. Es ist nicht allzu schwierig zu erkennen, ob zwei Achsen Zwillinge sind:

import numpy as np
import matplotlib.pyplot as plt


fig = plt.figure()
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)

t = np.arange(0.01, 10.0, 0.01)
s1 = np.exp(t)
ax1.plot(t, s1, 'b-')
ax1.set_xlabel('time (s)')
# Make the y-axis label and tick labels match the line color.
ax1.set_ylabel('exp', color='b')
for tl in ax1.get_yticklabels():
    tl.set_color('b')


ax3 = ax1.twinx()
s2 = np.sin(2*np.pi*t)
ax3.plot(t, s2, 'r.')
ax3.set_ylabel('sin', color='r')
for tl in ax3.get_yticklabels():
    tl.set_color('r')

print ax1.get_shared_x_axes().joined(ax1, ax2)
print ax1.get_shared_x_axes().joined(ax1, ax3)

print ax2.get_shared_x_axes().joined(ax2, ax1)
print ax2.get_shared_x_axes().joined(ax2, ax3)

print ax3.get_shared_x_axes().joined(ax3, ax1)
print ax3.get_shared_x_axes().joined(ax3, ax2)

plt.show()

Da die beiden Achsen einfach gestapelt sind, habe ich angenommen, dass alles an D3 übergeben wird, das die beiden Achsen einfach übereinander zeichnet. Ich habe dies mit einem einfachen Plugin überprüft und dies ist tatsächlich der Fall. Sowohl die exponentielle Line2D als auch die sin Line2D sind auf der D3-Seite vorhanden. Tatsächlich hat die Figur auf der D3-Seite zwei Achsen. Dies erklärt auch, warum die Ticks korrekt gerendert werden. Von den zweiten darüber gezeichneten Achsen ist nichts zu sehen.

OK, also sind beide Achsen gezeichnet, aber eine liegt über der anderen. Da sie einen undurchsichtigen weißen Hintergrund haben, wird der Inhalt der unteren Achsen ausgeblendet. Da sich Mausereignisse nicht durch die Achsenelemente ausbreiten, reagieren außerdem nur die oberen Achsen auf das Zoomen.

Um dies zu beheben, ist eine Überarbeitung des mpld3-Layouts erforderlich. Ich frage mich, wie Matplotlib selbst damit umgeht?

Exakt.

Es scheint, dass axis._frameon verwendet wird, um die Zeichnung sowohl des Hintergrund-Patches als auch des Rahmens um den Patch zu steuern. Frameon ist für die ersten Achsen wahr und für die zweiten Achsen falsch. Wenn wir jetzt frameon auf True setzen, sehen wir die zu den ersten Achsen gehörende Linie nicht mehr:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

t = np.arange(0.01, 10.0, 0.01)
s1 = np.exp(t)
ax1.plot(t, s1, 'b-')
ax1.set_xlabel('time (s)')
# Make the y-axis label and tick labels match the line color.
ax1.set_ylabel('exp', color='b')
for tl in ax1.get_yticklabels():
    tl.set_color('b')

ax2 = ax1.twinx()
s2 = np.sin(2*np.pi*t)
sin = ax2.plot(t, s2, 'r.')
ax2.set_ylabel('sin', color='r')
for tl in ax2.get_yticklabels():
    tl.set_color('r')

print ax1.get_frame_on()
print ax2.get_frame_on()

ax2.set_frame_on(True)

plt.show()

Dies deutet darauf hin, dass dieses Problem mit Nr. 186 zusammenhängt und dass die Adressierung des einen auch beim Adressieren des anderen helfen sollte.

Ach – das ist toll! Danke, dass du dich darauf eingelassen hast.

Wie möchten Sie dieses Problem angehen? Die naheliegendste Lösung wäre, frame_on weiterzugeben und die draw-Methode der mpld3_Axes zu modifizieren, um zu berücksichtigen, ob frame_on True oder False ist.

Beim Durchsuchen des Codes würde dies Änderungen in mplexporter und MPD3Renderer auf der Python-Seite und eine Änderung in mpld3Axes auf der Javascript-Seite nach sich ziehen.

Yep: mplexporter müsste aktualisiert werden, um frame_on zu passieren, und wenn es False ist, sollten die zugehörigen Linien und die Füllfarbe transparent sein.

Ich habe das Problem vermieden, indem ich ein Alpha auf den Hintergrund der zweiten Achse gesetzt habe.

ax2.patch.set_alpha(0.0)
ax2.patch.set_alpha(0.0)

lässt die Linien erscheinen, aber die Hover-, Pan- und Zoom-Tools funktionieren immer noch nicht auf den unteren Achsen. Gibt es eine Möglichkeit, die Werkzeuge auf allen Achsen arbeiten zu lassen?

Wenn ich mich nicht sehr irre, ist das immer noch ein Problem. Mit ax2.patch.set_alpha(0.0) kann ich meine beiden Zwillingsdiagramme sehen, aber Zoom / Pan funktioniert immer noch nur für die oberen Achsen. Die beiden Grafiken ändern sich, aber nur die x-Achse und die sekundäre y-Achse reagieren auf die neue Skalierung.

Ein weiteres Problem, das ich gefunden habe, ist, wenn Sie versuchen, drei x-Achsen zu verwenden. Der dritte sollte wie in diesem Beispiel beschrieben rechts sein, aber er funktioniert nicht so, wie er sein sollte. Der dritte überschreibt den zweiten. Das Zoom-Tool funktioniert bei mir immer noch nicht mit der twinx()-Methode. Ich hoffe, Sie können es bald beheben (Wenn ich Freizeit habe, werde ich es versuchen).

captura de tela de 2017-09-10 01-21-32

@fronchetti Dieses Projekt wird nicht mehr gepflegt und seit ein paar Jahren nicht mehr. Aus der README:

Hinweis: mpld3 wird nicht mehr aktiv gewartet: Funktionsanfragen und Fehlerberichte bleiben wahrscheinlich unbeantwortet. Wenn Sie daran interessiert sind, dieses Projekt zu pflegen, wenden Sie sich bitte an einen der Repository-Besitzer.

Es gibt viele andere Web-/Notebook-Plot-Optionen für Python: altair, bokeh, bqplot, um nur einige zu nennen. [Offenlegung: Ich bin ein Bokeh-Kernentwickler] Oder wenn Sie daran interessiert sind, dieses Projekt zu übernehmen, würde ich vorschlagen, Jake eine E-Mail zu senden.

Autsch! Ich habe diese Informationen nicht auf ihrer Website gesehen. Ich bin gerade hierher gekommen, um nach Problemen zu suchen, die mein Problem lösen könnten. Danke @bryevdv , ich werde eine andere

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

sheldonpark picture sheldonpark  ·  7Kommentare

jakevdp picture jakevdp  ·  4Kommentare

edvakf picture edvakf  ·  29Kommentare

dansteingart picture dansteingart  ·  31Kommentare

pranet picture pranet  ·  6Kommentare