Mpld3: ENH: twinx / twiny não está funcionando.

Criado em 7 mai. 2014  ·  17Comentários  ·  Fonte: mpld3/mpld3

twinx / twiny não estão funcionando como esperado. Eu sei que isso está na lista TODO, mas não há nenhum problema em aberto para isso ainda.

Parece que apenas o último conjunto de dados é plotado. Aqui está o exemplo oficial.

mpld3 retorna:
image

retorna tk-agg:
image

Código para reproduzir

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()

Comentários muito úteis

Evitei o problema definindo um alfa no plano de fundo do segundo eixo.

ax2.patch.set_alpha(0.0)

Todos 17 comentários

PS em Apresenta o último ponto de bala "ferramentas de interatividade adicionais, como brushing e box-zoom" provavelmente podem ser excluídas, já que box-zoom e brusing estão implementados.

Obrigado - imagino que esse será um problema aberto por um bom tempo ... consertá-lo envolveria algumas mudanças fundamentais no pacote.

Por curiosidade: o problema está no d3.js, mplexporter ou mpld3?

Será que um aviso poderia ser adicionado? (Twinx x ainda não implementado)

Hmm, ou melhor ainda, uma vez que os traços do quadro à direita são detectados, talvez eu pudesse fingir isso desenhando uma linha azul em escala no primeiro (eixos esquerdos). Vou tentar amanhã ...

Um aviso seria uma boa ideia. Deve acontecer em mplexporter/exporter.py . Não tenho certeza de como detectar isso melhor no objeto Axes. Provavelmente, a primeira etapa para descobrir como implementar isso é descobrir como disparar um aviso quando ele existir!

twinx() e twiny() resultam na criação de eixos adicionais que têm a mesma localização dos eixos originais. Detectar se dois eixos são gêmeos não é muito difícil:

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()

Dado que os dois eixos estão simplesmente empilhados, presumi que tudo fosse passado para D3, que simplesmente desenha os dois eixos um sobre o outro. Eu verifiquei isso com um plug-in simples e é realmente o caso. Tanto o Line2D exponencial quanto o sin Line2D estão presentes no lado D3. Na verdade, a figura do lado D3 tem dois eixos. Isso também explica por que os ticks são renderizados corretamente. Não há nada dos segundos eixos traçados sobre eles.

OK, então os dois eixos estão desenhados, mas um fica em cima do outro. Por terem um fundo branco opaco, o conteúdo dos eixos inferiores fica oculto. Além disso, como os eventos do mouse não se propagam pelos elementos dos eixos, apenas os eixos superiores respondem ao zoom.

Corrigir isso exigirá um retrabalho do layout mpld3. Eu me pergunto como o próprio matplotlib lida com isso?

Exatamente.

Parece que axes._frameon é usado para controlar o desenho tanto do patch de fundo quanto do quadro ao redor do patch. Frameon é verdadeiro para os primeiros eixos e falso para os segundos eixos. Se agora definirmos frameon como True, não veremos mais a linha pertencente aos primeiros eixos:

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()

Isso sugere que esse problema está relacionado ao nº 186 e que abordar um também deve ajudar a abordar o outro.

Ah - isso é ótimo! Obrigado por se aprofundar nisso.

Como você gostaria de resolver esse problema? A solução mais óbvia seria passar frame_on adiante e modificar o método de desenho dos mpld3_Axes para levar em consideração se frame_on é True ou False.

Ao navegar pelo código, isso implicaria em mudanças no mplexporter e no MPD3Renderer, no lado do python, e uma mudança no mpld3Axes no lado do javascript.

Sim: mplexporter teria que ser atualizado para passar por frame_on , e se for False, as linhas associadas e a cor de preenchimento devem ser transparentes.

Evitei o problema definindo um alfa no plano de fundo do segundo eixo.

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

permite que as linhas apareçam, mas as ferramentas de foco, panorâmica e zoom ainda não funcionam nos eixos inferiores. Existe uma maneira de permitir que as ferramentas funcionem em todos os eixos?

A menos que eu esteja muito enganado, isso ainda é um problema. Usando ax2.patch.set_alpha(0.0) , posso ver meus dois gráficos gêmeos, mas o zoom / panorâmica ainda funciona apenas para os eixos superiores. Ambos os gráficos mudam, mas apenas o eixo x e o eixo y secundário respondem à nova escala.

Outro problema que encontrei é se você tentar usar três eixos x. O terceiro deve estar correto, conforme descrito neste exemplo , mas não está funcionando como deveria. O terceiro substitui o segundo. A ferramenta de zoom ainda não está funcionando com o método twinx () para mim. Espero que você consiga consertar logo (se eu tiver tempo livre, tentarei).

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

@fronchetti este projeto não é mais mantido, e não é há alguns anos. Do README:

Nota: mpld3 não está mais sendo mantido ativamente: solicitações de recursos e relatórios de erros provavelmente não serão respondidos. Se você estiver interessado em manter este projeto, entre em contato com um dos proprietários do repositório.

Existem muitas outras opções de plotagem de web / notebook para Python: altair, bokeh, bqplot, apenas para citar alguns. [divulgação: eu sou um desenvolvedor do Bokeh core] Ou se você estiver interessado em assumir a propriedade deste projeto, sugiro enviar um e-mail para Jake.

Ai! Eu não vi essa informação no site deles. Só vim aqui em busca de problemas que pudessem resolver meu problema. Obrigado @bryevdv , vou tentar outra opção de plotagem.

Esta página foi útil?
0 / 5 - 0 avaliações