gpt4 book ai didi

python - 在两个表之间绘制箭头(作为图像)(Python)

转载 作者:行者123 更新时间:2023-12-03 20:49:05 24 4
gpt4 key购买 nike

我想绘制两个相邻的表格,并以特定方式在它们之间发射箭头(在 matplotlib 中)。到目前为止,我或多或少知道如何使用 plt.arrow为了让箭头做我想做的事,我找到了一篇文章,展示了如何仅绘制 plt.table 的表格部分.
https://towardsdatascience.com/simple-little-tables-with-matplotlib-9780ef5d0bc4
源代码,以防链接失效:

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)

(也许可以用函数整理 do it again。)
enter image description here
最终,我想得到类似以下草图的东西。
enter image description here
我愿意对我的方法进行细微的调整以完全改变我正在做的事情,甚至不使用 matplotlib ,但是我怎么能把我的想法变成一些代码来产生像我的草图这样的东西?

最佳答案

你快到了(也许同时已经解决了它),缺少的要点是你需要创建一个箭头(或者更确切地说是一个 ConnectionPatch ),它需要与整个图形(即 transform=fig.transFigure )一起转换而不是仅使用单个子图作为引用。请注意,此解决方案是 adapted from this answerhere是一些相关的文档。
完整代码:

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()
产生这个图像:
two tables connected with an arrow
请注意箭头起点和终点如何在子图坐标中给出(例如 (0.38,0.4) ,即您应该能够通过鼠标悬停快速找到好的点。

关于python - 在两个表之间绘制箭头(作为图像)(Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63866035/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com