Добавление изображения, созданного из другой библиотеки, в качестве вставки в matplotlib

Я создал сетевую фигуру, используя библиотеку vedo, и я пытаюсь добавить ее в качестве вставки к фигуре, созданной в matplotlib.

import networkx as nx
import matplotlib.pyplot as plt

from vedo import *
from matplotlib.offsetbox import OffsetImage, AnnotationBbox


G = nx.gnm_random_graph(n=10, m=15, seed=1)
nxpos = nx.spring_layout(G, dim=3, seed=1)

nxpts = [nxpos[pt] for pt in sorted(nxpos)]
nx_lines = [(nxpts[i], nxpts[j]) for i, j in G.edges()]

pts = Points(nxpts, r=12)
edg = Lines(nx_lines).lw(2)

# node values
values = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          [30, 80, 10, 79, 70, 60, 75, 78, 65, 10],
          [1, .30, .10, .79, .70, .60, .75, .78, .65, .90]]
time = [0.0, 0.1, 0.2]  # in seconds

vplt = Plotter(N=1)
pts1 = pts.cmap('Blues', values[0])
vplt.show(
    pts1, edg,
    axes=False,
    bg='white',
    at=0,
    interactive=False,
    zoom=1.5
).screenshot("network.png")

ax = plt.subplot(111)
ax.plot(
    [1, 2, 3], [1, 2, 3],
    'go-',
    label='line 1',
    linewidth=2
 )

arr_img = vplt.screenshot(returnNumpy=True, scale=1)
im = OffsetImage(arr_img, zoom=0.25)
ab = AnnotationBbox(im, (1, 0), xycoords='axes fraction', box_alignment=(1.1, -0.1), frameon=False)
ax.add_artist(ab)
plt.show()
ax.figure.savefig(
    "output.svg",
    transparent=True,
    dpi=600,
    bbox_inches="tight"
)

Там разрешение изображения на вставке слишком низкое. Предложения о том, как добавить вставку без потери разрешения, будут очень полезными.

РЕДАКТИРОВАТЬ: Ответ, опубликованный ниже, работает для добавления 2D-сети, но я все еще ищу способы, которые будут полезны для добавления 3D-сети во врезку.


person Natasha    schedule 23.12.2020    source источник


Ответы (1)


Я не знаком с vedo, но общая процедура заключается в создании inset_axis и построении изображения с помощью imshow. Однако ваш код использует networkx, который имеет привязки matplotlib, и вы можете сделать это напрямую без vedo.

РЕДАКТИРОВАТЬ: код отредактирован для 3D-графики

введите здесь описание изображения

import networkx as nx
import matplotlib.pyplot as plt

G = nx.gnm_random_graph(n=10, m=15, seed=1)
nxpos = nx.spring_layout(G, dim=3, seed=1)

nxpts = [nxpos[pt] for pt in sorted(nxpos)]
nx_lines = [(nxpts[i], nxpts[j]) for i, j in G.edges()]

# node values
values = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          [30, 80, 10, 79, 70, 60, 75, 78, 65, 10],
          [1, .30, .10, .79, .70, .60, .75, .78, .65, .90]]
time = [0.0, 0.1, 0.2]  # in seconds


fig, ax = plt.subplots()
ax.plot(
    [1, 2, 3], [1, 2, 3],
    'go-',
    label='line 1',
    linewidth=2
 )

from mpl_toolkits.mplot3d import (Axes3D)
from matplotlib.transforms import Bbox
rect = [.6, 0, .5, .5]
bbox = Bbox.from_bounds(*rect)
inax = fig.add_axes(bbox, projection = '3d')
# inax = add_inset_axes(, 
#                       ax_target = ax, 
#                       fig = fig, projection = '3d')

# inax.axis('off')


# set angle
angle = 25
inax.view_init(10, angle)

# hide axes, make transparent
# inax.set_facecolor('none')
# inax.grid('off')
import numpy as np

# plot 3d
seen = set()
for i, j in G.edges():
    x = np.stack((nxpos[i], nxpos[j]))
    inax.plot(*x.T, color = 'k')
    if i not in seen:
        inax.scatter(*x[0], color = 'skyblue')
        seen.add(i)
    if j not in seen:
        inax.scatter(*x[1], color = "skyblue")
        seen.add(j)

fig.show()

введите здесь описание изображения

person cvanelteren    schedule 23.12.2020
comment
Спасибо. Не могли бы вы подсказать, как добавить врезку 3D-сетевых графиков? Насколько я знаю, networkx создает только двумерные сетевые графики. - person Natasha; 23.12.2020
comment
Код отредактирован для 3D-графики. Networkx действительно не позволяет отображать ребра в 3D, узлы можно отображать в любых измерениях. приведенный выше код отражает 3D-графику. - person cvanelteren; 24.12.2020
comment
Я добавил запрос на включение для более строгого исправления. Спасибо! - person cvanelteren; 24.12.2020
comment
Замечательно! Спасибо - person Natasha; 24.12.2020