4

I am trying to make a plot in which the color scale is updated on zoom on the base of the visualized data, using a scheme similar to e.g. http://matplotlib.org/examples/event_handling/viewlims.html (also note similar question Matplotlib imshow, dynamically resample based on zoom)

However I met a problem when dealing with the colorbar, after removing it and adding a new one, the zoom history is reset. In my real code, the colorbar update is done at every zoom, as a result back and home buttons in matplotlib plot don't work at all.

This is probably clearer looking at the example code below. What is the reason? Is there a way to prevent this from happening?

The code, stripped from all unnecessary parts looks more or less like this:

#create and plot a test image with colorbar,
#zoom and everything works
import numpy as np
N=100
a=np.random.random((N,N))
plt.figure()
plt.imshow(a,interpolation='none')
plt.colorbar()
plt.show()
#at this point I can zoom and use back and forward buttons as always

#but if I zoom in and then execute the following code, the history is reset and I cannot go back or home any more (the zooming history works in the future, but is reset every time I replace the colorbar):
ax=plt.gca()
im=ax.images[-1]
im.colorbar.remove()
#in real code, color range is updated here
plt.colorbar()
4

1 に答える 1

1

残念ながら、これは困難であり、使用しているバックエンドにも少し依存します。ツールバーには 2 つのタイプがあります。通常はデフォルトである toolbar2 と、デフォルトになる toolmanager です。私のソリューションは、現在のデフォルトである toolbar2 に基づいています。

ここでの問題は、Figure の表示履歴がによる更新中にクリアされる 2 つのオブジェクト (および)figに格納されることです。したがって、私が簡単に考えることができる2つの解決策があります。cbook.Stackfig.canvas.toolbar._viewsfig.canvas.toolbar._positionsfig.canvas.toolbar.update()

1 つ目は、2 つのスタックをコピーしてから復元することです。

import copy
s = copy.copy( fig.canvas.toolbar._views )
p = copy.copy( fig.canvas.toolbar._positions )
ax=plt.gca()
im=ax.images[-1]
im.colorbar.remove()
#in real code, color range is updated here
plt.colorbar()
fig.canvas.toolbar._views = s
fig.canvas.toolbar._positions = p

NavigationToolbar22 つ目は、オブジェクトから update 関数を削除することです。例えば:

fig.canvas.toolbar.update = lambda: None

その後、履歴をリセットせずに元のコードが機能します。

ax=plt.gca()
im=ax.images[-1]
im.colorbar.remove()
#in real code, color range is updated here
plt.colorbar()

toolmanager については、backend_tools の ToolViewsPositions を確認する必要があります。

于 2016-02-11T10:47:44.463 に答える