linuxBean14.04(81)mpld3で目盛りラベルを変更する

ラベル: ,

前の関連記事:linuxBean14.04(80)mpld3でツールチップ


mpld3で目盛りラベルの変更はできないと思ってBokehに浮気しかけましたが、Tick labels & locations · Issue #22 · jakevdp/mpld3に載っているプラグインを使う方法で解決しました。ただし、目盛ラベルで指数を上付文字で表記することはできませんでした。

デフォルトで軸スケールに対数を指定するとeを使った表記になる

In [1]:
import matplotlib.pyplot as plt
import mpld3
In [2]:
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.plot([3,1,4,1,5,9,100,1000], 'ko-', mfc='k', mew=2, mec='w', ms=10)
mpld3.display()  # notebook以外ではmpld3.show()
Out[2]:

軸スケールに対数を指定するとデフォルトでは目盛りラベルはeを使った指数表示になります。
2e+2というのは$$$2\times10^{2}$$$、つまり200という意味です。

プラグインを作成して目盛りラベルと表示させる位置とその書式を指定する


Tick labels & locations · Issue #22 · jakevdp/mpld3 · GitHubに載っているHelloWorldプラグインを改変したものを使ったのですが、オリジナルのHelloWorldプラグインへのリンクが昨夜(2015.10.22)から表示されなくなっています。
In [3]:
class RedrawYTickValue(mpld3.plugins.PluginBase): 
    """RedrawYTickValue plugin"""
    JAVASCRIPT = """
    mpld3.register_plugin("redrawytickvalue", RedrawYTickValue);
    RedrawYTickValue.prototype = Object.create(mpld3.Plugin.prototype);
    RedrawYTickValue.prototype.constructor = RedrawYTickValue;
    function RedrawYTickValue(fig, props){mpld3.Plugin.call(this, fig, props);};
    RedrawYTickValue.prototype.draw = function(){
        var ax = this.fig.axes[0].elements[1]; // y軸を指定
        ax.axis.tickValues([1,10,100,1000]);  // 目盛りラベルを表示させる位置を指定。
        ax.axis.tickFormat(d3.format(",d"));  // 目盛りラベルの書式設定
        this.fig.reset(); 
    }
    """
    def __init__(self):
        self.dict_ = {"type": "redrawytickvalue"}
In [4]:
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.plot([3,1,4,1,5,9,100,1000], 'ko-', mfc='k', mew=2, mec='w', ms=10)
mpld3.plugins.connect(fig, RedrawYTickValue())
mpld3.display()  # notebook以外ではmpld3.show()
Out[4]:

Y軸の目盛りラベルの表記がRedrawYTickValueプラグインで指定した1,10,100,1000に変わりました。
目盛りラベルの書式一覧はFormatting · mbostock/d3 Wiki · GitHubにあります。

書式の指定方法はPythonの6.1.3.1. 書式指定ミニ言語仕様 (Format Specification Mini-Language)と同じになっています。

上記ではd3.format()の引数に",d"を指定してカンマ区切り書式にしていますので1000は1,000と表示されています。

x軸の目盛りラベルも変更する

今度はRedrawXTickValueを作ってX軸の目盛りラベルの書式を変更して小数点以下2桁まで表示させます。
In [5]:
class RedrawXTickValue(mpld3.plugins.PluginBase): 
    """RedrawXTickValue plugin"""
    JAVASCRIPT = """
    mpld3.register_plugin("redrawxtickvalue", RedrawXTickValue);
    RedrawXTickValue.prototype = Object.create(mpld3.Plugin.prototype);
    RedrawXTickValue.prototype.constructor = RedrawXTickValue;
    function RedrawXTickValue(fig, props){mpld3.Plugin.call(this, fig, props);};
    RedrawXTickValue.prototype.draw = function(){
        var ax = this.fig.axes[0].elements[0];  // x軸を指定
        ax.axis.tickValues([2,4,6]);  // 目盛りラベルを表示させる位置を指定。
        ax.axis.tickFormat(d3.format(".2f"));  // 目盛りラベルの書式設定
        this.fig.reset(); 
    }
    """
    def __init__(self):
        self.dict_ = {"type": "redrawxtickvalue"}
In [6]:
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.plot([3,1,4,1,5,9,100,1000], 'ko-', mfc='k', mew=2, mec='w', ms=10)
mpld3.plugins.connect(fig, RedrawXTickValue(), RedrawYTickValue())
mpld3.display()  # notebook以外ではmpld3.show()
Out[6]:

目盛りラベルを$$$10^{2}$$$という書式にする方法はわからず

目盛りラベルを$$$10^{2}$$$という書式にしてみたかったのですが解決できませんでした。
In [7]:
class RedrawYTickValue(mpld3.plugins.PluginBase): 
    """RedrawYTickValue plugin"""
    JAVASCRIPT = """
    mpld3.register_plugin("redrawytickvalue", RedrawYTickValue);
    RedrawYTickValue.prototype = Object.create(mpld3.Plugin.prototype);
    RedrawYTickValue.prototype.constructor = RedrawYTickValue;
    function RedrawYTickValue(fig, props){mpld3.Plugin.call(this, fig, props);};
    RedrawYTickValue.prototype.draw = function(){
        var ax = this.fig.axes[0].elements[1]; // y軸を指定
        ax.axis.tickValues([1,10,100,1000]);  // 目盛りラベルを表示させる位置を指定。
        ax.axis.tickFormat(function(x){
            var tickfmt = [];
            tickfmt[1] = "い";
            tickfmt[10] = "ろ";
            tickfmt[100] = "は";
            tickfmt[1000] = "に";
            return tickfmt[x];
        });  // 目盛りラベルの書式設定
        this.fig.reset(); 
    }
    """
    def __init__(self):
        self.dict_ = {"type": "redrawytickvalue"}
In [8]:
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.plot([3,1,4,1,5,9,100,1000], 'ko-', mfc='k', mew=2, mec='w', ms=10)
mpld3.plugins.connect(fig, RedrawYTickValue())
mpld3.display()  # notebook以外ではmpld3.show()
Out[8]:

配列tickfmtに表示させたいものをいれればよいところまではたどりついたのですが、LaTeX表記でもHTML表記でもソースのままテキストで表示されるので、$$$10^{2}$$$とは表示できませんでした。

参考にしたサイト


Welcome to Bokeh — Bokeh 0.10.0 documentation
mpld3に代わって使ってみようと思いましたがまだ簡単には使えないようです。

Tick labels & locations · Issue #22 · jakevdp/mpld3 · GitHub
ここに紹介されているプラグインを元に目盛りラベルの変更のプラグインを作りました。

Formatting · mbostock/d3 Wiki
d3.jsの目盛りラベルに指定できる書式一覧。

6.1.3.1. 書式指定ミニ言語仕様 (Format Specification Mini-Language)
d3.jsの目盛りラベルの指定できる書式の指定形式はPythonの書式指定と同じ形式です。

javascript - D3 - using strings for axis ticks - Stack Overflow
tickFormatを関数で返す方法を知りました。

r - rCharts nvd3 library force ticks - Stack Overflow
tickValuesとtickFormatの違いがわかりました。

D3 Plugins: Truly Interactive Matplotlib In Your Browser
mpld3の開発経緯が書かれています。

次の関連記事:linuxBean14.04(82)mpld3でツールチップ(やり直し編)

PR

2 件のコメント:

  1. 突然ですみません。
    私もissue#22を元にしてtick labelを作ることができましたが、
    ticklabelのrotation機能はどうしても作れないですが何かよいideaはあるのでしょうか

    返信削除
  2. ソースまで踏み込まずに無理矢理やるとしたら描画されたものをjQueryなどで後で修飾することでしょうか。

    返信削除