在两个表之间绘制箭头(作为图像)(Python)
我想绘制两个相邻表的绘图,其中箭头以特定方式在它们之间射出(在在两个表之间绘制箭头(作为图像)(Python),python,matplotlib,plot,Python,Matplotlib,Plot,我想绘制两个相邻表的绘图,其中箭头以特定方式在它们之间射出(在matplotlib中)。到目前为止,我或多或少知道如何使用plt.arrow来让箭头做我想做的事情,我发现了一篇文章,展示了如何仅绘制plt.table的表格部分 源代码,如果链接失效: import numpy as np import matplotlib.pyplot as plt title_text = 'Loss by Disaster' footer_text = 'June 24, 2020' fig_backgr
matplotlib
中)。到目前为止,我或多或少知道如何使用plt.arrow
来让箭头做我想做的事情,我发现了一篇文章,展示了如何仅绘制plt.table
的表格部分
源代码,如果链接失效:
import numpy as np
import matplotlib.pyplot as plt
title_text = 'Loss by Disaster'
footer_text = 'June 24, 2020'
fig_background_color = 'skyblue'
fig_border = 'steelblue'
data = [
[ 'Freeze', 'Wind', 'Flood', 'Quake', 'Hail'],
[ '5 year', 66386, 174296, 75131, 577908, 32015],
['10 year', 58230, 381139, 78045, 99308, 160454],
['20 year', 89135, 80552, 152558, 497981, 603535],
['30 year', 78415, 81858, 150656, 193263, 69638],
['40 year', 139361, 331509, 343164, 781380, 52269],
]
# Pop the headers from the data array
column_headers = data.pop(0)
row_headers = [x.pop(0) for x in data]
# Table data needs to be non-numeric text. Format the data
# while I'm at it.
cell_text = []
for row in data:
cell_text.append([f'{x/1000:1.1f}' for x in row])
# Get some lists of color specs for row and column headers
rcolors = plt.cm.BuPu(np.full(len(row_headers), 0.1))
ccolors = plt.cm.BuPu(np.full(len(column_headers), 0.1))
# Create the figure. Setting a small pad on tight_layout
# seems to better regulate white space. Sometimes experimenting
# with an explicit figsize here can produce better outcome.
plt.figure(linewidth=2,
edgecolor=fig_border,
facecolor=fig_background_color,
tight_layout={'pad':1},
#figsize=(5,3)
)
# Add a table at the bottom of the axes
the_table = plt.table(cellText=cell_text,
rowLabels=row_headers,
rowColours=rcolors,
rowLoc='right',
colColours=ccolors,
colLabels=column_headers,
loc='center')
# Scaling is the only influence we have over top and bottom cell padding.
# Make the rows taller (i.e., make cell y scale larger).
the_table.scale(1, 1.5)
# Hide axes
ax = plt.gca()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# Hide axes border
plt.box(on=None)
# Add title
plt.suptitle(title_text)
# Add footer
plt.figtext(0.95, 0.05, footer_text, horizontalalignment='right', size=6, weight='light')
# Force the figure to update, so backends center objects correctly within the figure.
# Without plt.draw() here, the title will center on the axes and not the figure.
plt.draw()
# Create image. plt.savefig ignores figure edge and face colors, so map them.
fig = plt.gcf()
plt.savefig('pyplot-table-demo.png',
#bbox='tight',
edgecolor=fig.get_edgecolor(),
facecolor=fig.get_facecolor(),
dpi=150
)
但是,我无法让两个表相邻打印并看起来很漂亮,并且两个表之间的箭头不会穿过两个打印区域
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2)
title_text = 'Loss by Disaster'
footer_text = 'June 24, 2020'
fig_background_color = 'skyblue'
fig_border = 'steelblue'
data = [
[ 'Freeze', 'Wind', 'Flood', 'Quake', 'Hail'],
[ '5 year', 66386, 174296, 75131, 577908, 32015],
['10 year', 58230, 381139, 78045, 99308, 160454],
['20 year', 89135, 80552, 152558, 497981, 603535],
['30 year', 78415, 81858, 150656, 193263, 69638],
['40 year', 139361, 331509, 343164, 781380, 52269],
]
# Pop the headers from the data array
column_headers = data.pop(0)
row_headers = [x.pop(0) for x in data]
# Table data needs to be non-numeric text. Format the data
# while I'm at it.
cell_text = []
for row in data:
cell_text.append([f'{x/1000:1.1f}' for x in row])
# Get some lists of color specs for row and column headers
rcolors = plt.cm.BuPu(np.full(len(row_headers), 0.1))
ccolors = plt.cm.BuPu(np.full(len(column_headers), 0.1))
# Create the figure. Setting a small pad on tight_layout
# seems to better regulate white space. Sometimes experimenting
# with an explicit figsize here can produce better outcome.
# ax1.figure(linewidth=2,
# edgecolor=fig_border,
# facecolor=fig_background_color,
# tight_layout={'pad':1},
# #figsize=(5,3)
# )
# Add a table at the bottom of the axes
the_table = ax1.table(cellText=cell_text,
rowLabels=row_headers,
rowColours=rcolors,
rowLoc='right',
colColours=ccolors,
colLabels=column_headers,
loc='center')
# Scaling is the only influence we have over top and bottom cell padding.
# Make the rows taller (i.e., make cell y scale larger).
the_table.scale(1, 1.5)
# Hide axes
ax1 = plt.gca()
ax1.get_xaxis().set_visible(False)
ax1.get_yaxis().set_visible(False)
#
# Do it again
#
the_table = ax2.table(cellText=cell_text,
rowLabels=row_headers,
rowColours=rcolors,
rowLoc='right',
colColours=ccolors,
colLabels=column_headers,
loc='center')
# Scaling is the only influence we have over top and bottom cell padding.
# Make the rows taller (i.e., make cell y scale larger).
the_table.scale(1, 1.5)
# Hide axes
ax2 = plt.gca()
ax2.get_xaxis().set_visible(False)
ax2.get_yaxis().set_visible(False)
#
plt.arrow(0.5, 0.5, -5, 1)
(也许可以用一个函数来整理再做一次。)
最后,我想得到下面的草图
我愿意对我的方法进行一些小的调整,以完成我正在做的事情,甚至不使用matplotlib
,但我如何才能将我的想法整合到一些代码中,从而产生类似于我的草图的东西呢?你就快到了(可能同时已经解决了这个问题),缺少的要点是,您需要创建一个箭头(或者更确切地说是一个连接补丁
),该箭头需要与整个图形进行变换(即transform=fig.transFigure
),而不是仅使用单个子图作为参考。请注意,此解决方案是并且是一些相关文档
完整代码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch
fig, (ax1, ax2) = plt.subplots(1, 2,figsize=(10,5))
title_text = 'Loss by Disaster'
footer_text = 'June 24, 2020'
fig_background_color = 'skyblue'
fig_border = 'steelblue'
data = [
[ 'Freeze', 'Wind', 'Flood', 'Quake', 'Hail'],
[ '5 year', 66386, 174296, 75131, 577908, 32015],
['10 year', 58230, 381139, 78045, 99308, 160454],
['20 year', 89135, 80552, 152558, 497981, 603535],
['30 year', 78415, 81858, 150656, 193263, 69638],
['40 year', 139361, 331509, 343164, 781380, 52269],
]
# Pop the headers from the data array
column_headers = data.pop(0)
row_headers = [x.pop(0) for x in data]
# Table data needs to be non-numeric text. Format the data
# while I'm at it.
cell_text = []
for row in data:
cell_text.append([f'{x/1000:1.1f}' for x in row])
# Get some lists of color specs for row and column headers
rcolors = plt.cm.BuPu(np.full(len(row_headers), 0.1))
ccolors = plt.cm.BuPu(np.full(len(column_headers), 0.1))
# Create the figure. Setting a small pad on tight_layout
# seems to better regulate white space. Sometimes experimenting
# with an explicit figsize here can produce better outcome.
# ax1.figure(linewidth=2,
# edgecolor=fig_border,
# facecolor=fig_background_color,
# tight_layout={'pad':1},
# #figsize=(5,3)
# )
# Add a table at the bottom of the axes
the_table = ax1.table(cellText=cell_text,
rowLabels=row_headers,
rowColours=rcolors,
rowLoc='right',
colColours=ccolors,
colLabels=column_headers,
loc='center')
# Scaling is the only influence we have over top and bottom cell padding.
# Make the rows taller (i.e., make cell y scale larger).
the_table.scale(1, 1.5)
# Do it again
#
the_table = ax2.table(cellText=cell_text,
rowLabels=row_headers,
rowColours=rcolors,
rowLoc='right',
colColours=ccolors,
colLabels=column_headers,
loc='center')
# Scaling is the only influence we have over top and bottom cell padding.
# Make the rows taller (i.e., make cell y scale larger).
the_table.scale(1, 1.5)
### actually turn axes off:
for a in [ax1,ax2]:
a.set_axis_off()
con = ConnectionPatch(xyA=(0.38,0.4), xyB=(0.43, 0.52),
coordsA="data", coordsB="data",
axesA=ax1, axesB=ax2,
shrinkA=1, shrinkB=1,
ec="red", fc="w", linewidth=2, alpha=1,
arrowstyle="-|>",connectionstyle="arc3",
mutation_scale=20, )
ax2.add_artist(con)
plt.show()
生成此图像:
注意箭头起点和终点是如何在子批次坐标中给出的(例如(0.38,0.4)
,即您应该能够通过鼠标悬停快速找到好的点