用Matplotlib绘制围棋棋盘
在matplotlib中画一个围棋棋盘可能吗?我不会给你看我那些糟糕的尝试(里面有些是用补丁做的),除非你要求我分享,我希望你能想出更好的主意。
或者更好的是:有没有现成的库可以用,或者有人已经写过这个功能?那就太好了!
(为什么有人需要在matplotlib中使用围棋棋盘呢?理由可多了。我的人工智能程序本身就是用python/C++写的,还需要一些性能的可视化,而这些可视化是用matplotlib绘制的。现在可以导出/导入到.sgf格式,但这需要一个外部查看器,如果需要很多图表的话,这个查看器会很慢。)
1 个回答
8
当然可以。任何东西都可以画出来,这只是需要多少代码的问题...
import matplotlib.pyplot as plt
# create a 8" x 8" board
fig = plt.figure(figsize=[8,8])
fig.patch.set_facecolor((1,1,.8))
ax = fig.add_subplot(111)
# draw the grid
for x in range(19):
ax.plot([x, x], [0,18], 'k')
for y in range(19):
ax.plot([0, 18], [y,y], 'k')
# scale the axis area to fill the whole figure
ax.set_position([0,0,1,1])
# get rid of axes and everything (the figure background will show through)
ax.set_axis_off()
# scale the plot area conveniently (the board is in 0,0..18,18)
ax.set_xlim(-1,19)
ax.set_ylim(-1,19)
# draw Go stones at (10,10) and (13,16)
s1, = ax.plot(10,10,'o',markersize=30, markeredgecolor=(0,0,0), markerfacecolor='w', markeredgewidth=2)
s2, = ax.plot(13,16,'o',markersize=30, markeredgecolor=(.5,.5,.5), markerfacecolor='k', markeredgewidth=2)
这样就能得到:
如果你不喜欢背景,还可以用 imshow
放上一些好看的围棋棋盘照片或者其他你需要的东西。
一个不错的地方是,如果你拿到 ax.plot
返回的对象,你可以把它们删掉,然后重新画棋盘,这样就不用做太多工作了。
ax.lines.remove(s1)
或者简单点
s1.remove()
第一个方法展示了发生了什么;线对象从线列表中被移除了,第二个方法输入起来更快,因为线对象知道它的父级。
无论哪种方法,效果都一样。(你可能需要调用 draw
来查看更改。)
在Python中,有很多方法可以实现同样的事情,matplotlib
也不例外。根据 tcaswell
的建议,线条被网格替代,圆形标记则用圆形补丁代替。此外,现在黑白棋子是从原型创建的。
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import copy
fig = plt.figure(figsize=[8,8], facecolor=(1,1,.8))
ax = fig.add_subplot(111, xticks=range(19), yticks=range(19), axis_bgcolor='none', position=[.1,.1,.8,.8])
ax.grid(color='k', linestyle='-', linewidth=1)
ax.xaxis.set_tick_params(bottom='off', top='off', labelbottom='off')
ax.yaxis.set_tick_params(left='off', right='off', labelleft='off')
black_stone = mpatches.Circle((0,0), .45, facecolor='k', edgecolor=(.8,.8,.8, 1), linewidth = 2, clip_on=False, zorder=10)
white_stone = copy.copy(black_stone)
white_stone.set_facecolor((.9, .9, .9))
white_stone.set_edgecolor((.5, .5, .5))
s1 = copy.copy(black_stone)
s1.center = (18,18)
ax.add_patch(s1)
s2 = copy.copy(white_stone)
s2.center = (6,10)
ax.add_patch(s2)
结果基本上是一样的。