Matplotlib SVG: Zachowaj wykres i grafikę logo jako ścieżki
Wyeksportuj wykres z Matplotlib jako SVG, połącz go z osobnymi ścieżkami logo za pomocą svgutils i sprawdź plik przekazywany odbiorcy pod kątem osadzonych pikseli, rozmieszczenia i zmian czcionek.
Na tej stronie
- Wybierz, co powinno znaleźć się w kodzie źródłowym wykresu
- Co zawierają pliki przekazywane odbiorcy
- Wyeksportuj wykres z przewidywalnymi granicami
- Połącz grafikę z wykresem bez jej rasteryzacji
- Sprawdź plik, a następnie przetestuj zmianę
- Odtwarzaj tylko grafikę, która tego wymaga
- Najczęściej zadawane pytania
- Źródła
Aby zachować logo w postaci wektorowej na rysunku z Matplotlib, wyeksportuj wykres jako SVG i połącz go z istniejącą geometrią SVG logo. Umieszczenie pliku PNG za pomocą OffsetImage może dać plik SVG zawierający obraz rastrowy obok wektorowych linii wykresu. Samo rozszerzenie nie mówi, które części są ścieżkami.
W tym poradniku rozdzielamy te zadania: Matplotlib rysuje wykres na podstawie danych, a svgutils umieszcza obok niego ozdobny emblemat. Jeśli oryginalna grafika jest już wektorowa, użyj jej. Jeśli zachowała się tylko odpowiednia ilustracja rastrowa, odtwórz ją osobno. Znaczniki wartości liczbowych, osie i etykiety zachowaj w kodzie źródłowym wykresu.
Proces w skrócie
Wyeksportuj wykres, połącz go z osobną grafiką, sprawdź wynikowy plik SVG, a następnie ponownie otwórz dokładnie ten plik, który przekażesz odbiorcy. Zachowaj skrypt rysujący wykres i plik źródłowy grafiki, aby po kolejnej zmianie danych można było ponownie wygenerować rysunek.
Wybierz, co powinno znaleźć się w kodzie źródłowym wykresu
Logo to grafika; znacznik podziałki osi to część wykresu. Traktowanie obu jako jednego obrazu utrudnia późniejsze zmiany.
| Zawartość rysunku | Preferowane źródło | Co sprawdzić |
|---|---|---|
| Linie, znaczniki, osie i etykiety danych | Kod rysujący wykres w Matplotlib | Wartości, etykiety i sposób przedstawienia danych |
| Istniejące wektorowe logo lub ilustracja | Źródłowy plik SVG | Ścieżki, granice i zależności |
| Fotografia rastrowa lub panel z obrazem mikroskopowym | Oryginalny obraz rastrowy | Rozdzielczość w docelowym rozmiarze |
| Prosty motyw dekoracyjny, którego źródło wektorowe zaginęło | Osobno sprawdzona wstępna wersja odtworzonej grafiki | Wierność kształtów i niepożądane obszary |
Rysunek nie musi być w całości wektorowy, jeśli niektóre panele są fotografiami. Zachowaj je jako obrazy rastrowe. Celem jest zachowanie właściwego źródła każdego elementu, a następnie sprawdzenie złożonego wyniku.
Dokumentacja savefig w Matplotlib opisuje jawny wybór formatu wyjściowego. API OffsetImage opisuje kontener obrazu, a nie importer ścieżek SVG. Diagnostykę na poziomie pliku znajdziesz w poradniku jak znaleźć obrazy rastrowe wewnątrz SVG.
Co zawierają pliki przekazywane odbiorcy
Uruchomiliśmy przykład z użyciem Pythona 3.12, Matplotlib 3.10.7 i svgutils 0.3.4. Emblemat jest autorskim rysunkiem złożonym z dwóch ścieżek. Cztery wartości na wykresie to dane poglądowe, a nie wyniki eksperymentu ani testu porównawczego produktu.
Porównanie wykorzystuje ten sam wykres w obu plikach. Po lewej stronie emblemat PNG o wymiarach 32 × 32 wstawiono za pomocą OffsetImage. Po prawej jego ścieżki SVG połączono z wyeksportowanym wykresem. Powiększone fragmenty pochodzą z tych rzeczywistych plików przekazywanych odbiorcy.

Zliczenie elementów SVG dało następujące wyniki:
| Plik | Elementy image | Elementy path | Elementy text |
|---|---|---|---|
| Sam wykres | 0 | 8 | 15 |
| Wykres z emblematem PNG | 1 | 8 | 15 |
| Wykres ze ścieżkami SVG emblematu | 0 | 10 | 15 |
Te liczby dotyczą tego niewielkiego przykładu testowego. Liczba ścieżek nie jest miarą jakości, a brak elementów image nie dowodzi, że wszystkie właściwości pliku SVG zostaną zachowane w innej aplikacji. Potwierdza jednak, że emblemat w tym złożonym pliku jest geometrią, a nie osadzonym plikiem PNG.
Wyeksportuj wykres z przewidywalnymi granicami
Zainstaluj w środowisku projektu wersje użyte w tym przykładzie:
python -m pip install matplotlib==3.10.7 svgutils==0.3.4Zapisz poniższy kod jako plot.py i uruchom go w pustym folderze roboczym:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
plt.rcParams["svg.fonttype"] = "none"
fig = plt.figure(figsize=(6, 3), dpi=72)
ax = fig.add_axes([0.14, 0.22, 0.58, 0.65])
ax.plot([0, 1, 2, 3], [1, 2, 1.5, 3],
marker="o", color="#173b40")
ax.set(xlabel="Example x", ylabel="Example y",
title="Illustrative data only")
ax.spines[["top", "right"]].set_visible(False)
fig.savefig("plot.svg", format="svg")
plt.close(fig)Osie zajmują tylko część rysunku, pozostawiając miejsce na emblemat po prawej stronie. Ten eksport ma viewBox o wartości 0 0 432 216 i wymiary zewnętrzne 432pt na 216pt.
Zachowaj te granice podczas umieszczania zewnętrznej grafiki. Dodanie bbox_inches="tight" zmienia granice zapisanego rysunku, co wyjaśnia dokumentacja savefig. Jeśli potrzebujesz przycięcia ściśle do granic zawartości, sprawdź wyeksportowany viewBox, a następnie zaktualizuj współrzędne kompozycji.
Ustawienie svg.fonttype="none" zachowuje etykiety z przykładu jako tekst. Dokumentacja czcionek w Matplotlib opisuje opcje zapisu tekstu SVG i ścieżek. Edytowalny tekst nadal wymaga odpowiedniej czcionki w środowisku odbiorcy. Jeśli potrzebujesz niezmiennych kształtów liter, świadomie wybierz zapis w postaci ścieżek i zachowaj kod źródłowy wykresu do edycji etykiet. Poradnik o zmianach czcionek w SVG omawia ten kompromis.
Połącz grafikę z wykresem bez jej rasteryzacji
Zapisz ten autorski emblemat jako badge.svg obok plot.svg:
<svg xmlns="http://www.w3.org/2000/svg"
width="100" height="100" viewBox="0 0 100 100">
<path fill="#173b40" fill-rule="evenodd"
d="M30 5H70L95 30V70L70 95H30L5 70V30Z
M34 17L17 34V66L34 83H66L83 66V34L66 17Z"/>
<path fill="#28bfa3" d="M53 23L30 55H47L43 77L70 43H53Z"/>
</svg>Następnie uruchom ten skrypt składający kompozycję:
import svgutils.transform as sg
page = sg.SVGFigure("432pt", "216pt")
page.root.set("viewBox", "0 0 432 216")
chart = sg.fromfile("plot.svg").getroot()
badge = sg.fromfile("badge.svg").getroot()
badge.moveto(332, 76, scale_x=0.64)
page.append([chart, badge])
page.save("vector-logo.svg")Ten kod stosuje schemat wczytania, przekształcenia, dołączenia i zapisania opisany w poradniku składania rysunków w svgutils. Użyliśmy scale_x, argumentu obsługiwanego przez svgutils 0.3.4; starszy poradnik pokazuje inny argument skalowania.
Grafika emblematu o szerokości 100 jednostek uzyskuje szerokość 64 jednostek. Jej lewy górny róg znajduje się w punkcie (332, 76) w układzie współrzędnych wykresu. Jawnie określone wymiary zewnętrzne i viewBox zapewniają jednoznaczne rozmieszczenie w tym przykładzie testowym. Są to współrzędne strony, a nie współrzędne danych: przesunięcie punktu danych na wykresie nie przesunie wraz z nim emblematu.
W przypadku adnotacji powiązanych ze zmieniającym się punktem danych utrzymuj jawnie zdefiniowane odwzorowanie współrzędnych wykresu na wyeksportowaną stronę albo użyj narzędzia do składania kompozycji, które zapewnia takie powiązanie. Stała pozycja na stronie sprawdza się w przypadku logo w rogu lub osobnego panelu ilustracyjnego.
Źródłowy plik SVG może zawierać także inne elementy niż ścieżki. Plik SVG, który już zawiera osadzony PNG, po połączeniu nadal ma zawartość mieszaną. Przy łączeniu bardziej złożonych plików sprawdź także identyfikatory, do których istnieją odwołania, czcionki i zasoby połączone zewnętrznymi odnośnikami. Emblemat w tym przykładzie nie ma takich zależności.
Sprawdź plik, a następnie przetestuj zmianę
Otwórz vector-logo.svg w przeglądarce lub docelowym edytorze. Sprawdź centralny otwór emblematu, etykiety wykresu i pustą przestrzeń między nimi. Obejrzyj plik zarówno w rozmiarze, w którym faktycznie go użyjesz, jak i w powiększeniu.
Krótka kontrola XML pozwala potwierdzić strukturę bez polegania na podglądzie:
import xml.etree.ElementTree as ET
root = ET.parse("vector-logo.svg").getroot()
ns = "{http://www.w3.org/2000/svg}"
for tag in ("image", "path", "text"):
print(tag, len(root.findall(".//" + ns + tag)))Dla podanego przykładu testowego kod wypisuje image 0, path 10 i text 15. Wersja rastrowa użyta do porównania wypisuje image 1, zachowując osiem ścieżek wykresu. W tej wersji odwołanie do obrazu zawiera dane PNG; jest to zawartość rastrowa osadzona w pliku, a nie brakujący zewnętrzny plik logo.
Teraz zmień ostatnią poglądową wartość y w plot.py, uruchom go ponownie i ponownie uruchom skrypt składający kompozycję. Wykres powinien się zmienić, a emblemat pozostać w zarezerwowanej dla niego pozycji na stronie. Taki test pozwala wykryć sytuację, w której proces daje poprawny wynik przy pierwszym wykonaniu, ale zależy od starego eksportu wykresu.
Osobno sprawdź kolejny etap przekazywania pliku. Jeśli rysunek trafi do dokumentu, poradnik pracy z SVG w LaTeX wyjaśnia opcje eksportu i etykiet. Sam poprawny podgląd w przeglądarce nie potwierdza zgodności z wymaganiami czasopisma ani zachowania elementów w końcowym pliku PDF.
Odtwarzaj tylko grafikę, która tego wymaga
Jeśli istnieje kod źródłowy wykresu, wyeksportuj wykres z niego. Wektoryzacja nie może odtworzyć danych liczbowych ani poleceń rysujących wykres ze zrzutu ekranu.
PerfectVector sprawdza się w węższym przypadku, gdy proste dekoracyjne logo lub ilustracja zachowały się tylko jako obraz rastrowy. Korzystając z procesu odtwarzania grafiki naukowej, przytnij obraz do tej grafiki, obejrzyj podgląd wstępnej wersji grafiki wektorowej i sprawdź otwory, cienkie kształty oraz niepożądane obszary tła. Nie obejmuj wektoryzacją osi, znaczników pomiarowych ani etykiet. Połącz zaakceptowaną grafikę SVG z wykresem wygenerowanym bezpośrednio z kodu, a następnie powtórz kontrolę pliku przekazywanego odbiorcy.
Używaj oryginalnego źródła wektorowego, gdy tylko je masz. Przerysuj prosty znak ręcznie, jeśli obrysowywanie gubi istotny szczegół. Zachowaj panele fotograficzne jako obrazy rastrowe. Omówienie wektoryzacji obrazów wyjaśnia, co można odtworzyć przez obrysowywanie, zanim wybierzesz tę metodę.
Najczęściej zadawane pytania
Czy zapisanie rysunku z Matplotlib jako SVG sprawia, że logo PNG staje się wektorowe? Nie. W przetestowanym procesie z użyciem OffsetImage wykres jest eksportowany jako geometria wektorowa, natomiast logo PNG pozostaje elementem image wewnątrz SVG.
Czy mogę umieścić logo SVG za pomocą współrzędnych danych? Pokazana tutaj kompozycja wykorzystuje współrzędne wyeksportowanej strony. Logo powiązane z punktem danych wymaga jawnego odwzorowania współrzędnych albo narzędzia, które utrzymuje to powiązanie.
Dlaczego moje etykiety stały się ścieżkami? Ustawienie sposobu zapisu czcionek SVG w Matplotlib określa, czy etykiety są eksportowane jako tekst, czy jako ścieżki glifów. Wybierz to ustawienie przed eksportem i zachowaj kod źródłowy wykresu, aby później zmieniać treść etykiet.
Źródła
- Matplotlib — savefig — Jawny eksport SVG i wpływ ramek ograniczających dopasowanych do zawartości.
- Matplotlib — OffsetImage — Działanie kontenera obrazu wykorzystane w porównaniu z wersją rastrową.
- Matplotlib — Fonts in Matplotlib — Opcje zapisu tekstu SVG i ścieżek glifów.
- svgutils — Creating publication-quality figures — Osobny eksport wykresu, składanie SVG, przekształcenia i zapis złożonego rysunku.
Wyeksportuj wykres z jego kodu i zachowaj grafikę osobno. Jeśli pozostał tylko rastrowy motyw dekoracyjny, przygotuj wstępną wersję grafiki SVG, sprawdź jej otwory i granice, a następnie połącz ją z wykresem i sprawdź dokładnie ten plik, który przekażesz odbiorcy, pod kątem pikseli, rozmieszczenia i zmian etykiet.
Więcej z bloga

jsPDF SVG: Zachowaj ścieżki logo w PDF-ie utworzonym w przeglądarce
Użyj svg2pdf.js z jsPDF, aby umieścić logo SVG, zachować obsługiwane ścieżki, ustawić jego rozmiar w PDF-ie i porównać zapisany plik ze zrasteryzowanym eksportem tej grafiki.

SVG w WPF: wybierz renderer lub rysunek XAML
Używaj grafiki SVG w WPF za pomocą renderera, natywnego DrawingImage lub eksportu do PNG. Prześledź autorski przykład ikony i sprawdź granice, kolory oraz zależności.