pceccon
pceccon

Reputation: 9844

Draw a plot of glyphs in Matplotlib

I was using Matplotlib to plot some scientific visualizations for which heat map plots (as the one below) was sufficient. My code is all written in Python too.

enter image description here

However, now I need to present a more "elaborated" plot, which consists of glyphs. The following image (the second one) shows an example:

enter image description here

In that image, each point of the plot is a glyph that represents a probability of a vector field orientation. This is glyph is draw as a circle with a main direction and a standard deviation from its direction.

I would like to do something similar. My idea was to draw something like a polar histogram at each position and to have a plot comprised by polar charts. However, I don't think that is possible with Matplotlib; at least I don't have any idea how this can be done. As my whole code is written in Python, I was wondering if somehow I can stand with Matplotlib, or if I should study how to do this with OpenGL or another API/libraty.

Thank you.

Upvotes: 2

Views: 2585

Answers (1)

cphlewis
cphlewis

Reputation: 16259

Perhaps a whole lot of something like this:

enter image description here

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import PatchCollection
from matplotlib.patches import Wedge, Circle
from math import degrees, pi

fig, ax = plt.subplots()
wedges = []
circles = []

for x in np.arange(0, 3.3, .3):
    for y in np.arange(0, 3.3, .3):
        theta, phi = np.random.random(2)  # functions of (x,y) in reality
        for v in (0, pi):
            wedges.append(Wedge((x, y),
                            .15,
                            degrees(v - phi - theta/2),
                            degrees(v - phi + theta/2),
                            edgecolor='none'),
                            )
        circles.append(Circle((x, y),
                             .15,
                             edgecolor='none'))


colors = np.linspace(0, 1, len(circles))  # function of (x,y) in reality
collection = PatchCollection(circles, cmap=plt.cm.jet, alpha=0.2)
collection.set_array(np.array(colors))
collection.set_edgecolor('none')
ax.add_collection(collection)

#wedgecolors = list(chain.from_iterable(repeat(i,2) for i in colors))
wedgecolors = np.array([colors, colors]).flatten('F') # no itertools
collection = PatchCollection(wedges, cmap=plt.cm.jet, alpha=1)
collection.set_array(np.array(wedgecolors))
collection.set_edgecolor('none')
ax.add_collection(collection)

ax.set_xlim(0,3)
ax.set_ylim(0,3)
ax.set_aspect('equal')
plt.show()

(Setting the edgecolor has to be done (redone?) after the collection.set_array call, apparently.)

Upvotes: 2

Related Questions