matplotlibの三次元プロットの見栄えを良くする その1
seabornはmatplotlibの二次元プロットの見栄えを良くしてくれるが, 三次元となるとうまくいかない. これはseabornのせいというよりもむしろ, matplotlibでの二次元と三次元の扱いが全く別である上に, 三次元では相当にパラメータのハードコードが行われているせいようのようだ. matplotlib 1.5.1ではこの辺り良くなりつつあるのでseabornもそのうち対応するかもしれない.
とはいえ, 今見栄えを良くしたい. plotlyを使う手もあるがmatplotlibでそこそこがんばってみる.
from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d.axis3d import Axis import matplotlib.pyplot as plt import matplotlib as mpl from matplotlib import cm import itertools import seaborn as sns color_palette = sns.color_palette() # color_palette = [ # (0.2980392156862745, 0.4470588235294118, 0.6901960784313725), # (0.3333333333333333, 0.6588235294117647, 0.40784313725490196), # (0.7686274509803922, 0.3058823529411765, 0.3215686274509804), # (0.5058823529411764, 0.4470588235294118, 0.6980392156862745), # (0.8, 0.7254901960784313, 0.4549019607843137), # (0.39215686274509803, 0.7098039215686275, 0.803921568627451)] fig = plt.figure(figsize=(8, 8), dpi=80) ax = plt.subplot(111, projection='3d') ax.set_axis_bgcolor('white') # background color for axis in (ax.xaxis, ax.yaxis, ax.zaxis): # axis._axinfo.update({ # # 'label' : {'va': 'center', 'ha': 'center'}, # # 'tick' : {'inward_factor': 0.2, 'outward_factor': 0.1}, # # 'axisline': {'linewidth': 0.5, 'color': (0, 0, 0, 1)}, # 'grid' : {'color': (1, 1, 1, 1),'linewidth': 1.0}, # }) # the grid color and width axis._axinfo['grid']['color'] = (1, 1, 1, 1) axis._axinfo['grid']['linewidth'] = 1.0 for tick in axis.get_major_ticks(): tick.label.set_fontsize(16) # ticks label font size. 12 as a default # set label texts. 'labelpad' means the distance between axis and label ax.set_xlabel('X', fontsize=24, labelpad=14) ax.set_ylabel('Y', fontsize=24, labelpad=14) ax.set_zlabel('Z', fontsize=24, labelpad=14) for axis in (ax.w_xaxis, ax.w_yaxis, ax.w_zaxis): axis.line.set_color("white") # a color of each axis axis.set_pane_color((0.848, 0.848, 0.848, 1.0)) # a color of each pane # axis.set_pane_color((0.9176470588235294, 0.9176470588235294, 0.9490196078431372, 1.0)) # much more like the seaborn style # make all ticks lines invisible for line in itertools.chain(ax.get_xticklines(), ax.get_yticklines(), ax.get_zticklines()): line.set_visible(False) #XXX: START x = np.arange(-3, 3, 0.25) y = np.arange(-3, 3, 0.25) X, Y = np.meshgrid(x, y) Z = np.sin(X)+ np.cos(Y) # ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis, linewidth=0, antialiased=False) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=sns.cubehelix_palette(8, start=0.5, rot=-0.75, as_cmap=True), linewidth=0, antialiased=False) #XXX: END plt.subplots_adjust(left=0, right=1, top=1, bottom=0) plt.show()
カラーマップにseabornのものを指定しているが, matplotlib 1.5.1では標準でviridisが使えるのでそちらが良いだろう.
Python3とmatplollib 1.5.1で試した. matplotlibの1.4系列などでは動かないかも.