在Matplotlib中,如何将3D图作为插图包含进去?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Matplotlib中,如何将3D图作为插图包含进去?相关的知识,希望对你有一定的参考价值。
我目前可以做插图,但只能是2D的。 在Matplotlib中,我可以添加 projection='3d'
到 fig1.add_axes()
或 inset_axes()
的代码将无法使用。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from mpl_toolkits.axes_grid.inset_locator import inset_axes
x = np.linspace(0,2.0*np.pi,51)
y = np.sin(x)
def make_plot(x,y):
fig = plt.figure(figsize=(10,7))
rect = [0.18,0.18,0.25,0.25]
ax = fig.add_subplot(111)
ax.grid()
ax.set_xlim(x.min(),x.max())
ax.plot(x,y,'bo-')
fig1 = plt.gcf()
ax_inset1 = fig1.add_axes(rect,anchor='NW',axisbg=None) # , projection='3d')
ax_inset2 = inset_axes(ax, width="40%", height=1.8, loc=1) # , projection='3d')
ax_inset1.plot(x,y,'r--'); ax_inset1.set_xlim(x.min(),x.max())
ax_inset2.plot(x,y,'g--'); ax_inset2.set_xlim(x.min(),x.max())
X, Y, Z = axes3d.get_test_data(0.05)
#ax_inset1.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
plt.show()
make_plot(x,y)
以下是由上述代码生成的图片。
]1
如何修改上面的代码,使其中一个(或两个)插页有3D图?
答案
迟了几年,但我希望在这里找到答案。在matplotlib 3.1.3中,这个工作。
使用下面的代码与 fig
参数也应该允许在3D投影上进行 "插入"。
import numpy as np
import matplotlib.pyplot as plt
# required for "3d" projection even though not explicitly used
from mpl_toolkits.mplot3d import axes3d
from matplotlib.transforms import Bbox
def add_inset_axes(rect, units="ax", ax_target=None, fig=None, projection=None, **kw):
"""
Wrapper around `fig.add_axes` to achieve `ax.inset_axes` functionality
that works also for insetting 3D plot on 2D ax/figures
"""
assert ax_target is not None or fig is not None, "`fig` or `ax_target` must be provided!"
_units = {"ax", "norm2ax", "norm2fig"}
assert {units} <= _units, "`rect_units` not in {}".format(repr(_units))
if ax_target is not None:
# Inspired from:
# https://stackoverflow.com/questions/14568545/convert-matplotlib-data-units-to-normalized-units
bb_data = Bbox.from_bounds(*rect)
trans = ax_target.transData if units == "ax" else ax_target.transAxes
disp_coords = trans.transform(bb_data)
fig = ax_target.get_figure()
fig_coord = fig.transFigure.inverted().transform(disp_coords)
elif fig is not None:
if ax_target is not None and units != "norm2fig":
bb_data = Bbox.from_bounds(*rect)
trans = ax_target.transData if units == "ax" else ax_target.transAxes
disp_coords = trans.transform(bb_data)
else:
fig_coord = Bbox.from_bounds(*rect)
axin = fig.add_axes(
Bbox(fig_coord),
projection=projection, **kw)
return axin
x = np.linspace(0,2.0*np.pi,51)
y = np.sin(x)
fig = plt.figure(figsize=(10,7))
rect = [0.1, 0.15, 0.4, 0.4]
rect2 = [3.5, 0, 2.5, 1]
ax = fig.add_subplot(111)
ax.grid()
ax.set_xlim(x.min(),x.max())
ax.plot(x,y,'bo-')
# This works actually
ax_inset1 = fig.add_axes(rect, anchor='NW', projection='3d')
ax_inset1.plot(x,y,'r--')
# In case you wanted to make the background of the 3d plot transparent
ax_inset1.patch.set_alpha(0.)
ax_inset1.xaxis.set_alpha(0.)
ax_inset1.yaxis.set_alpha(0.)
ax_inset1.zaxis.set_alpha(0.)
# This one does not work because the inset is assumed to be the same type of plot...
# ax_inset2 = ax.inset_axes(rect, projection='3d')
# Here is a convenient helper function to achieve the same functionaly
# plus some extra sugar
# Convenient wrapper around `fig.add_axes`
ax_inset2 = add_inset_axes(rect2, units="ax", ax_target=ax, projection="3d")
ax_inset2.plot(x,y,'g--')
save_fig(fig, "Stackoverflow.png")
plt.show()
结果。
以上是关于在Matplotlib中,如何将3D图作为插图包含进去?的主要内容,如果未能解决你的问题,请参考以下文章
python使用matplotlib可视化3D柱状图(3D bar plot三维柱状图包含三个坐标轴xyz)设置zdir参数为x改变3d图观察的角度
如何在 matplotlib mplot3D 或类似文件中显示 3D 数组等值面的 3D 图?
如何将 3d GLViewWidget 插入包含 2d PyQtGraph 图的窗口中
python使用matplotlib可视化3D柱状图(3D histogram三维柱状图包含三个坐标轴xyz)设置zdir参数为z改变3d图观察的角度