Imaging simulation slice and adding a shape - python

I have been making slice images of a simulation, now I need to add a shape to the image, the slice has a colour map, I add a circle to the slice, I need help with making the circle colour be adjustable by values, and share the same colormap as the slice.The code I use is:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import csv
def readslice(ndim):
shape = (ndim,ndim,ndim)
fd = open("delta_T_v3_no_halos_z013.40_nf0.898994_useTs0_zetaX-1.0e+00_alphaX-1.0_TvirminX-1.0e+00_aveTb027.03_Pop-1_300_200Mpc", 'rb')
data = np.fromfile(file=fd, dtype= np.dtype('f4')).reshape(shape)
fd.close()
print data
return data
ff = readslice(300)
circle1=plt.Circle((150.0,150.0),50.0)
fig = plt.gcf()
fig.gca().add_artist(circle1)
plt.imshow(ff[0,:,:],cmap = cm.jet)
plt.colorbar()
plt.savefig('picwithcircle.png')
plt.show()

Related

How to retrieve the raw figure data from matplotlib?

I am using matplotlib to generate matrices I can train on. I need to get to the raw figure data.
Saving and reading the .png works fine, but my code runs 10x longer. Another stack overflow asked a similar question and the solution was to grab the canvas, but that related logic generated a numpy error. Here is my mwe.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import IdentityTransform
px = 1/plt.rcParams['figure.dpi'] # pixel in inches
fig, ax = plt.subplots(figsize=(384*px, 128*px))
i = 756
plt.text(70, 95, "value {:04d}".format(i), color="black", fontsize=30, transform=IdentityTransform())
plt.axis('off')
plt.savefig("xrtv.png") # I dont want to do this ...
rtv = plt.imread("xrtv.png") # or this, but I want access to what imread returns.
gray = lambda rgb: np.dot(rgb[..., :3], [0.299, 0.587, 0.114])
gray = gray(rtv)
Disabling rendering was a good hint. Consider using a memory buffer to I/O rather than playing with strings. Here is a full example:
import numpy as np
import io
import matplotlib.pyplot as plt
from PIL import Image
# disable rendering and dump to buffer
plt.ioff()
fig,ax = plt.subplots()
ax.plot(np.sin(np.arange(100)))
buf = io.BytesIO()
fig.savefig(buf,format='RGBA')
# plot from buffer
shape = (int(fig.bbox.bounds[-1]),int(fig.bbox.bounds[-2]),-1)
img_array = np.frombuffer(buf.getvalue(),dtype=np.uint8).reshape(shape)
Image.fromarray(img_array)

How to extract rgb values of this colorbar image in python?

Image
I want to make a colormap used in the attached image colorbar. So far I tried the code given below but didn't get the result I was looking for.
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
img = plt.imread('Climat.png')
colors_from_img = img[:, 0, :]
my_cmap = LinearSegmentedColormap.from_list('my_cmap', colors_from_img, N=651)
y = random_sample((100, 100))
imshow(y, cmap=my_cmap);plt.colorbar()
Looking for your suggestions. Thank you in advance.
bicarlsen has given you the correct direction. Restrict the points from which you extract the colors to the colored rectangles:
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
img = plt.imread('Climat.png')
colors_from_img = img[80::88, 30, :]
my_cmap = LinearSegmentedColormap.from_list('my_cmap', colors_from_img[::-1], N=len(colors_from_img))
y = np.random.random_sample((100, 100))
plt.imshow(y, cmap=my_cmap)
plt.colorbar()
plt.show()
Sample output:
P.S.: Initially, I thought a more general approach with
colors_from_img = np.unique(img[:, 30, :], axis=0)
was possible but as the input image is rasterized, all kinds of mixed colors are present where the black lines separate colored rectangles.

3D graph in yt module

could you help me with this code, please? I am trying to integrate the force line in the given point. I don't know where is a mistake - there is no streamline in the plot.
Data - dipole magnetic field are here
I tried this example with the change of data and the change of number of streamlines.
import numpy as np
import matplotlib.pyplot as plt
from numpy import array
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D # 3d graph
from mpl_toolkits.mplot3d import proj3d # 3d graph
import math
from matplotlib import patches
import code
import yt
from yt import YTArray # arrays in yt module
from yt.visualization.api import Streamlines # force lines
import matplotlib.pylab as pl# Choose point in field
X_point = 0.007089085922957821
Y_point = 0.038439192046320805
Z_point = 0# Load data (dictionary)
try:
import cPickle as pickle
except ImportError: # python 3.x
import picklewith open('data.p', 'rb') as fp:
data = pickle.load(fp)Bx_d = data["Bx"]
By_d = data["By"]
Bz_d = data["Bz"]# 3d array of dipole magnetic field
print(type(data))
bbox = np.array([[-0.15, 0.15], [0, 0.2], [-0.1, 0.1]]) # box, border
ds = yt.load_uniform_grid(data, Bx_d.shape, length_unit="Mpc", bbox=bbox, nprocs=100) # data, dimensionc = YTArray([X_point, Y_point, Z_point], 'm') # Define c: the center of the box, chosen point
c1 = ds.domain_center
print('c1', c1)
print(type(c1))
print('center',c)
N = 1 # N: the number of streamlines
scale = ds.domain_width[0] # scale: the spatial scale of the streamlines relative to the boxsize,
pos = c# Create streamlines of the 3D vector velocity and integrate them through
# the box defined above
streamlines = Streamlines(ds, pos, 'Bx', 'By', 'Bz', length=None) # length of integration
streamlines.integrate_through_volume()# Create a 3D plot, trace the streamlines through the 3D volume of the plot
fig=pl.figure()
ax = Axes3D(fig)
ax.scatter(X_point, Y_point, Z_point, marker = 'o', s=40, c='green')
print('tisk', streamlines.streamlines)for stream in streamlines.streamlines:
stream = stream[np.all(stream != 0.0, axis=1)]
ax.plot3D(stream[:,0], stream[:,1], stream[:,2], alpha=0.1)# Save the plot to disk.
pl.savefig('streamlines.png')
plt.show()
Output:
Without knowing more about the data, as well as what the output of the print call is, it's not entirely clear what the error is. If the streamlines have meaningful values (i.e., the values of stream[:,0] etc are within the bounds of your Axes3D, it should produce results.
Options for debugging would start with examining the individual values, then proceeding to plotting them in 2D (using pairs of components of each stream -- (0,1), (1,2) and (0,2)), and then examining what happens if you allow Axes3D to autoscale the xyz axes. You may also experiment with the alpha value, to see if the lines are simply too light to see.
An example image that this produces would also help, so that it can be made clear a few things about the properties matplotlib assigns to the Axes3D object.

How to use numpy to build a 3D-model?

Original(2018.11.01)
I have 3 numpy:x、y、z,created by my laser scanner(40 degree / 1 step).
I want to used them to build a 3D model.
I think it must should be use matplotlib.tri
But I have no idea to decide triangulated data
Here is my data :https://www.dropbox.com/s/d9p62kv9jcq9bwh/xyz.zip?dl=0
And Original model:https://i.imgur.com/XSyONff.jpg
Code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.tri as mtri
x_all=np.load("x.npy")
y_all=np.load("y.npy")
z_all=np.load("z.npy")
tri = #I have no idea...
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(x_all,y_all,z_all,triangles=tri.triangles)
Thank so much.
Update(2018.11.02)
I try this way to decide triangulated data
Delaunay Triangulation of points from 2D surface in 3D with python?
code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.tri as mtri
from stl import mesh
x_all=np.load("x.npy")
y_all=np.load("y.npy")
z_all=np.load("z.npy")
model=np.vstack((x_all,y_all,z_all))
model=np.transpose(model)
model -= model.mean(axis=0)
rad = np.linalg.norm(model, axis=1)
zen = np.arccos(model[:,-1] / rad)
azi = np.arctan2(model[:,1], model[:,0])
tris = mtri.Triangulation(zen, azi)
plt.show()
And my model looks like:
https://i.stack.imgur.com/KVPHP.png
https://i.stack.imgur.com/LLQsQ.png
https://i.stack.imgur.com/HdzFm.png
Even though it has better surface on it,but there is a big hole over my model.Any idea to fixs it?
Assuming you want to reduce the complexity, i.e find triangles in your files to reduce the complexity. You may look into fitting a convex hull to your points, see here fore more info
Based on the file you provided this produces a surf plot of the object.
from numpy import load, stack
from matplotlib.pyplot import subplots
from mpl_toolkits.mplot3d import Axes3D
from scipy import spatial
x = load("x.npy")
y = load("y.npy")
z = load("z.npy")
points = stack((x,y,z), axis = -1)
v = spatial.ConvexHull(points)
fig, ax = subplots(subplot_kw = dict(projection = '3d'))
ax.plot_trisurf(*v.points.T, triangles = v.simplices.T)
fig.show()

Transform numpy array to RGB image array

Consider the following code:
import numpy as np
rand_matrix = np.random.rand(10,10)
which generates a 10x10 random matrix.
Following code to display as colour map:
import matplotlib.pyplot as plt
plt.imshow(rand_matrix)
plt.show()
I would like to get the RGB numpy array (no axis) from the object obtained from plt.imshow
In other words, if I save the image generated from plt.show, I would like to get the 3D RGB numpy array obtained from:
import matplotlib.image as mpimg
img=mpimg.imread('rand_matrix.png')
But without the need to save and load the image, which is computationally very expensive.
Thank you.
You can save time by saving to a io.BytesIO instead of to a file:
import io
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from PIL import Image
def ax_to_array(ax, **kwargs):
fig = ax.figure
frameon = ax.get_frame_on()
ax.set_frame_on(False)
with io.BytesIO() as memf:
extent = ax.get_window_extent()
extent = extent.transformed(fig.dpi_scale_trans.inverted())
plt.axis('off')
fig.savefig(memf, format='PNG', bbox_inches=extent, **kwargs)
memf.seek(0)
arr = mpimg.imread(memf)[::-1,...]
ax.set_frame_on(frameon)
return arr.copy()
rand_matrix = np.random.rand(10,10)
fig, ax = plt.subplots()
ax.imshow(rand_matrix)
result = ax_to_array(ax)
# view using matplotlib
plt.show()
# view using PIL
result = (result * 255).astype('uint8')
img = Image.fromarray(result)
img.show()

Categories