twinx/twiny 未按预期工作。 我知道这在 TODO 列表中,但目前还没有未解决的问题。
似乎只绘制了最后一个数据集。 这是官方的例子。
mpld3 返回:
tk-agg 返回:
重现代码
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()
PS 在Features下的最后一个要点“其他交互工具,例如刷涂和框缩放”可能可以删除,因为框缩放和刷涂都已实现。
谢谢 - 我想这将是一个悬而未决的问题……修复它会涉及对包的一些非常基本的更改。
出于好奇:问题出在 d3.js、mplexporter 还是 mpld3 中?
也许可以添加警告? (Twinx x 尚未实现)
嗯,或者更好的是,因为右侧的帧刻度确实被拾取,也许我可以通过在第一个(左轴)上绘制一条缩放的蓝线来伪造这一点。 明天试试...
警告将是一个好主意。 它应该发生在mplexporter/exporter.py
。 我不确定如何在 Axes 对象中最好地检测到这一点。 弄清楚如何实现这一点的第一步可能是弄清楚如何在警告存在时发出警告!
twinx()
和twiny()
导致创建与原始轴具有相同位置的附加轴。 检测两个轴是否是双胞胎并不太难:
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()
鉴于两个轴只是堆叠在一起,我假设所有内容都传递给 D3,它只是将两个轴相互叠加。 我用一个简单的插件检查了这个,确实是这样。 指数 Line2D 和 sin Line2D 都出现在 D3 侧。 实际上,D3 侧的图形有两个轴。 这也解释了为什么正确呈现刻度的原因。 在它们上方绘制的第二个轴没有任何内容。
好的,所以两个轴都被绘制了,但是一个在另一个上面。 因为它们有一个不透明的白色背景,下轴的内容是隐藏的。 此外,由于鼠标事件不会通过轴元素传播,因此只有顶部轴响应缩放。
解决这个问题需要对 mpld3 布局进行一些重新设计。 我想知道 matplotlib 本身是如何处理这个的?
确切地。
似乎axes._frameon 用于控制背景补丁以及补丁周围框架的绘制。 Frameon 对于第一个轴为真,对于第二个轴为假。 如果我们现在将 frameon 设置为 True,我们将不再看到属于第一个轴的线:
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()
这表明这个问题与#186 相关,解决一个问题也应该有助于解决另一个问题。
啊——太好了! 感谢您深入研究。
您希望如何解决这个问题? 最明显的解决方案是传递 frame_on 并修改 mpld3_Axes 的 draw 方法以考虑 frame_on 是 True 还是 False。
通过浏览代码,这将需要更改 python 端的 mplexporter 和 MPD3Renderer,并更改 javascript 端的 mpld3Axes。
是的:必须更新 mplexporter 以通过frame_on
,如果它是 False 关联的线条和填充颜色应该是透明的。
我通过在第二个轴的背景上设置 alpha 来避免这个问题。
ax2.patch.set_alpha(0.0)
ax2.patch.set_alpha(0.0)
允许显示线条,但悬停、平移和缩放工具在较低的轴上仍然不起作用。 有没有办法让工具在所有轴上工作?
除非我大错特错,否则这仍然是一个问题。 使用ax2.patch.set_alpha(0.0)
我可以看到我的双图,但缩放/平移仍然只适用于顶部轴。 两个图形都会发生变化,但只有 x 轴和辅助 y 轴响应新的缩放比例。
我发现的另一个问题是,如果您尝试使用三个 x 轴。 第三个应该在这个例子中描述的右边,但它没有像它应该的那样工作。 第三个覆盖第二个。 缩放工具对我来说仍然无法使用 twinx() 方法。 希望你能尽快修复它(如果我有空闲时间,我会尝试)。
@fronchetti这个项目不再维护,而且已经有几年了。 从自述文件:
注意:mpld3 不再被积极维护:功能请求和错误报告可能没有得到答复。 如果您有兴趣维护此项目,请联系其中一位存储库所有者。
Python 还有很多其他的网络/笔记本绘图选项:altair、bokeh、bqplot,仅举几例。 [披露:我是 Bokeh 核心开发人员] 或者,如果您有兴趣获得该项目的所有权,我建议给 Jake 发送电子邮件。
哎哟! 我没有在他们的网站上看到这些信息。 我只是来这里寻找可以解决我的问题的问题。 谢谢@bryevdv ,我会尝试另一个绘图选项。
最有用的评论
我通过在第二个轴的背景上设置 alpha 来避免这个问题。