Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement self-defined scatter shape marker by matplotlib

2025-02-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article is about how matplotlib implements custom scatter-shaped markers. Xiaobian thinks it is quite practical, so share it with everyone for reference. Let's follow Xiaobian and have a look.

Unfilled and filled shapes

To use this shape, simply specify a character or a number for the marker

Tex Shape

You can copy a custom string in Latex format to marker, so if you want makrer to be a number or a word letter or a special symbol, you can define such a string.

import matplotlib.pyplot as plt import numpy as np data = np.random.rand(3,2)fig = plt.figure() ax = fig.add_subplot(111) markers = ["$\u266B$", r"$\frac{1}{2}$", "$\heartsuit$"]for i in range(data.shape[0]): ax.scatter(data[i,0], data[i,1], marker=markers[i], s=400) plt.show()

Path object

The definition of Path class in matplotlib refers to the definition of image format svg format, which is not explained in detail, but can be used by Baidu itself. Path object provides great convenience for customizing marker. Some Path classes defined in Path module can be used for user combination. Users can also customize Path classes.

Use the Path object in the Path module import matplotlib.pyplot as pltimport matplotlib.path as mpathimport numpy as npstar = mpath.Path.unit_regular_star(6) #Star Pathcircle = mpath.Path.unit_circle() #Circle Path #Points that integrate two Path objects verts = np.concatenate([circle.vertices, star.vertices[::-1,...])# Merge two path object point types codes = np.concatenate([circle.codes, star.codes])#Regenerate a new Path object based on path point and point types cut_star = mpath.Path(vers, codes)plt.plot(np.arange(10)**2, '--r', marker=cut_star, markersize=15)plt.show()

custom Path object import matplotlib.pyplot as pltimport matplotlib.path as mpathimport numpy as npccircle = mpath.Path.unit_circle() #Get a circle vers_part= circle.wedge(340,220).vertices #Path points of a partial circle counterclockwise from 340 degrees to 220 degrees codes_part = circle.wedge(340,220).codes #Point type vers_part = vers_part[1:-2] #Remove the first and last two points codes_part = codes_part [1:-2] #Integrate new points verts = np.concatenate([np.array([[0,-2]]), verts_part, np.array([[0,-2]])]) codes = [mpath.Path.MOVETO] + codes_part.tolist() + [mpath.Path.CLOSEPOLY] icon = mpath.Path(verts = vers, codes=codes)plt.plot(vers [:,0], vers [:,1]) plt.show ()

plt.scatter(data[:,0], data[:,1], marker=icon, s=300, facecolor="none",edgecolors="black")plt.show()

Convert svg format to Path object

Since the definition of the Path class originates from svg, it raises the question of whether an svg-formatted image can be converted into a Path object. This way we don't have to define our own Path object, but we can convert an image in svg format that someone else has defined into a Path object.

The answer is yes, you can use svgpath3mpl library to parse svg into matplotlib Path object

import matplotlib as mpl from svgpath3mpl import parse_pathimport xml.etree.ElementTree as etree from six import StringIO import re# svg format svg code svg = """"#parse code tree = etree.parse (StringIO(svg)) root = tree.getroot() width = int (re.match(r'\d+', root.attrib['width']).group())height = int(re.match(r'\d+', root.attrib['height']).group())path_elems = root.findall('.// {http://www.w3.org/2000/svg}path') #Resolve each Path pair paths = [parse_path(elem.attrib['d ']) for elem in path_elems] facecolors = [elem.attrib.get('fill', 'none') for elem in path_elems] facecolors = [c if c != "" else "none" for c in facecolors]edgecolors = [elem.attrib.get('stroke', 'none') for elem in path_elems]linewidths = [elem.attrib.get('stroke_width', 1) for elem in path_elems]#defining rotation matrix def rot(vers, az): #Rotate clockwise rad = az / 180 * np.pi verts = np.array(verts) rotMat = np.array([[np.cos(rad), -np.sin(rad)], [np.sin(rad), np.cos(rad)]]) transVerts = verts.dot(rotMat) return transVerts#Merge each Path object verts = paths[0].vertices codes = paths[0].codes for i in range(1,len(paths)): verts = np.concatenate([verts, paths[i].vertices]) codes = np.concatenate([codes, paths[i].codes])verts = rot(verts, 180) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(verts[:,0], verts[:,1] , color="red") plt.show()

#Define parsing function def svg2path(svg): #Parse code tree = etree.parse(StringIO(svg)) root = tree.getroot() path_elems = root.findall('.// {http://www.w3.org/2000/svg}path') #Parse out each Path object paths = [parse_path(elem.attrib['d']) for elem in path_elems] #Merge path objects verts = paths[0].vertices codes = paths[0].codes for i in range(1, len(paths)): verts = np.concatenate([verts, paths[i].vertices]) codes = np.concatenate([codes, paths[i].codes]) #Return to original shape verts = rot(verts, 270) vers = np.fliplr(vers) #Flip horizontally, mirror #verts = (verts - verts.min(0)) / (verts.max(0) - verts.min(0)) icon = mpath.Path(vertices=verts, codes=codes) return iconsvg = ["""""", """""", """"""]icons = []for s in svg: icons.append(svg2path(s))fig = plt.figure() ax = fig.add_subplot(111) for i in range(data.shape[0]): ax.scatter(data[i,0], data[i,1], marker=icons[i], s=3000)plt.show()

Thank you for reading! About "matplotlib how to achieve custom dot shape marker" this article is shared here, I hope the above content can be of some help to everyone, so that everyone can learn more knowledge, if you think the article is good, you can share it to let more people see it!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report