How do I apply a material to a .glb/.gltf mesh? - python

I have a model in .glb format with nothing edit(but a mesh) in the scene. How do I apply a material of a glb/gltf mesh using Python? I am using Pygltflib and Trimesh although I can use other libraries.

I can only give a genereal answer, because you did not provide any code, but you would do it like this in principal:
material = Material() # Create a material
pbr = PbrMetallicRoughness() # Use PbrMetallicRoughness
pbr.baseColorFactor = [1.0, 0.0, 0.0, 1.0] # solid red
material.pbrMetallicRoughness = pbr
after that supply the material to your primitive like that
primitive.material = 0
and do not forget to add it to the gltf. As always if you use more materials, the order will be important of course:
gltf.materials.append(material)
For completeness here is how to add a double sided red metallicRoughnessMaterial with "MASK" alphaMode to the triangle example and save it as .glb:
from pygltflib import *
# create gltf objects for a scene with a primitive triangle with indexed geometry
gltf = GLTF2()
scene = Scene()
mesh = Mesh()
material = Material()
primitive = Primitive()
node = Node()
buffer = Buffer()
bufferView1 = BufferView()
bufferView2 = BufferView()
accessor1 = Accessor()
accessor2 = Accessor()
# add data
buffer.uri = "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA="
buffer.byteLength = 44
bufferView1.buffer = 0
bufferView1.byteOffset = 0
bufferView1.byteLength = 6
bufferView1.target = ELEMENT_ARRAY_BUFFER
bufferView2.buffer = 0
bufferView2.byteOffset = 8
bufferView2.byteLength = 36
bufferView2.target = ARRAY_BUFFER
accessor1.bufferView = 0
accessor1.byteOffset = 0
accessor1.componentType = UNSIGNED_SHORT
accessor1.count = 3
accessor1.type = SCALAR
accessor1.max = [2]
accessor1.min = [0]
accessor2.bufferView = 1
accessor2.byteOffset = 0
accessor2.componentType = FLOAT
accessor2.count = 3
accessor2.type = VEC3
accessor2.max = [1.0, 1.0, 0.0]
accessor2.min = [0.0, 0.0, 0.0]
pbr = PbrMetallicRoughness() # Use PbrMetallicRoughness
pbr.baseColorFactor = [1.0, 0.0, 0.0, 1.0] # solid red
material.pbrMetallicRoughness = pbr
material.doubleSided = True # make material double sided
material.alphaMode = MASK # to get around 'MATERIAL_ALPHA_CUTOFF_INVALID_MODE' warning
primitive.attributes.POSITION = 1
primitive.material = 0
node.mesh = 0
scene.nodes = [0]
# assemble into a gltf structure
gltf.scenes.append(scene)
gltf.meshes.append(mesh)
gltf.materials.append(material)
gltf.meshes[0].primitives.append(primitive)
gltf.nodes.append(node)
gltf.buffers.append(buffer)
gltf.bufferViews.append(bufferView1)
gltf.bufferViews.append(bufferView2)
gltf.accessors.append(accessor1)
gltf.accessors.append(accessor2)
gltf.convert_buffers(BufferFormat.BINARYBLOB) # Convert buffers to allow saving as .glb
# save to a .glb file
gltf.save("triangle.glb")

Related

How to implement a lane change manoeuver on Carla

I am trying to implement a simple lane change manoeuver for a self driving car on Carla simulator. Specifically a left lane change.
However when retrieving waypoints from the left lane ( using carla.Waypoint.get_left_lane() function ), the waypoints I get are oscillating between left and right lanes. Below is the script I used :
import sys
import glob
import os
try:
sys.path.append(glob.glob('../../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import time
import math
import numpy as np
import random
from agents.navigation.controller import VehiclePIDController
dt = 1.0 / 20.0
args_lateral_dict = {'K_P': 1.95, 'K_I': 0.05, 'K_D': 0.2, 'dt': dt}
args_longitudinal_dict = {'K_P': 1.0, 'K_I': 0.05, 'K_D': 0, 'dt': dt}
max_throt = 0.75
max_brake = 0.3
max_steer = 0.8
offset = 0
VEHICLE_VEL = 5
actorList = []
try:
client = carla.Client("localhost",2000)
client.set_timeout(10.0)
world = client.load_world("Town02")
spectator = world.get_spectator()
actorList.append(spectator)
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 1/20
world.apply_settings(settings)
blueprint_library = world.get_blueprint_library()
vehicle_bp = blueprint_library.filter("cybertruck")[0]
vehicle = None
while(vehicle is None):
spawn_points = world.get_map().get_spawn_points()
spawn_point = random.choice(spawn_points) if spawn_points else carla.Transform()
vehicle = world.try_spawn_actor(vehicle_bp, spawn_point)
actorList.append(vehicle)
vehicle_controller = VehiclePIDController(vehicle,
args_lateral=args_lateral_dict,
args_longitudinal=args_longitudinal_dict,
offset=offset,
max_throttle=max_throt,
max_brake=max_brake,
max_steering=max_steer)
old_yaw = math.radians(vehicle.get_transform().rotation.yaw)
old_x = vehicle.get_transform().location.x
old_y = vehicle.get_transform().location.y
```
spectator_transform = vehicle.get_transform()
spectator_transform.location += carla.Location(x = 10, y= 0, z = 5.0)
control = carla.VehicleControl()
control.throttle = 1.0
vehicle.apply_control(control)
while True:
####### Im suspecting the bug is within this portion of code ########################
current_waypoint = world.get_map().get_waypoint(vehicle.get_location())
# if not turned_left :
left_waypoint = current_waypoint.get_left_lane()
if(left_waypoint is not None and left_waypoint.lane_type == carla.LaneType.Driving) :
target_waypoint = left_waypoint.previous(0.3)[0]
turned_left = True
else :
if(turned_left) :
target_waypoint = waypoint.previous(0.3)[0]
else : # I tryed commenting this else section but the bug is still present so I dont suspect the bug relates to this else part
target_waypoint = waypoint.next(0.3)[0]
################### End of suspected bug ############################################
world.debug.draw_string(target_waypoint.transform.location, 'O', draw_shadow=False,
color=carla.Color(r=255, g=0, b=0), life_time=120.0,
persistent_lines=True)
control_signal = vehicle_controller.run_step(VEHICLE_VEL,target_waypoint)
vehicle.apply_control(control_signal)
new_yaw = math.radians(vehicle.get_transform().rotation.yaw)
spectator_transform = vehicle.get_transform()
spectator_transform.location += carla.Location(x = -10*math.cos(new_yaw), y= -10*math.sin(new_yaw), z = 5.0)
spectator.set_transform(spectator_transform)
world.tick()
finally:
print("Destroying actors")
client.apply_batch([carla.command.DestroyActor(x) for x in actorList])
I just figured out the cause of the problem. The reason is that I was manipulating Carla waypoints as undirected points. However, in Carla, each waypoint is directed by the road direction.
In the scene, I was testing my code in, all the roads have two lanes, each one in an opposite direction. Hence, the left lane of each lane is the remaining lane.
The issue in the previous code was that I was not changing my view to match the direction of the lane. I was assuming a global reference frame, but in Carla, the waypoints are relative to the frames attached to their respective lanes. And since only one of the two coordinate frames (for each lane) was matching my imagined global reference frame, I was getting an oscillatory behavior.
Another issue was that I was updating the target waypoints to track too early. This caused the vehicle to move a very short distance without going through all the target waypoints. I changed this to keep tracking the same target waypoint until the distance separating it to my vehicle becomes too close before moving to the next waypoint. This helped to perform the lane change behavior.
Below is the script I used :
import sys
import glob
import os
#The added path depends on where the carla binaries are stored
try:
sys.path.append(glob.glob('../../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import time
import math
import numpy as np
import random
from agents.navigation.controller import VehiclePIDController
VEHICLE_VEL = 5
class Player():
def __init__(self, world, bp, vel_ref = VEHICLE_VEL, max_throt = 0.75, max_brake = 0.3, max_steer = 0.8):
self.world = world
self.max_throt = max_throt
self.max_brake = max_brake
self.max_steer = max_steer
self.vehicle = None
self.bp = bp
while(self.vehicle is None):
spawn_points = world.get_map().get_spawn_points()
spawn_point = random.choice(spawn_points) if spawn_points else carla.Transform()
self.vehicle = world.try_spawn_actor(vehicle_bp, spawn_point)
self.spectator = world.get_spectator()
dt = 1.0 / 20.0
args_lateral_dict = {'K_P': 1.95, 'K_I': 0.05, 'K_D': 0.2, 'dt': dt}
args_longitudinal_dict = {'K_P': 1.0, 'K_I': 0.05, 'K_D': 0, 'dt': dt}
offset = 0
self.controller = VehiclePIDController(self.vehicle,
args_lateral=args_lateral_dict,
args_longitudinal=args_longitudinal_dict,
offset=offset,
max_throttle=max_throt,
max_brake=max_brake,
max_steering=max_steer)
self.vel_ref = vel_ref
self.waypointsList = []
self.current_pos = self.vehicle.get_transform().location
self.past_pos = self.vehicle.get_transform().location
def dist2Waypoint(self, waypoint):
vehicle_transform = self.vehicle.get_transform()
vehicle_x = vehicle_transform.location.x
vehicle_y = vehicle_transform.location.y
waypoint_x = waypoint.transform.location.x
waypoint_y = waypoint.transform.location.y
return math.sqrt((vehicle_x - waypoint_x)**2 + (vehicle_y - waypoint_y)**2)
def go2Waypoint(self, waypoint, draw_waypoint = True, threshold = 0.3):
if draw_waypoint :
# print(" I draw")
self.world.debug.draw_string(waypoint.transform.location, 'O', draw_shadow=False,
color=carla.Color(r=255, g=0, b=0), life_time=10.0,
persistent_lines=True)
current_pos_np = np.array([self.current_pos.x,self.current_pos.y])
past_pos_np = np.array([self.past_pos.x,self.past_pos.y])
waypoint_np = np.array([waypoint.transform.location.x,waypoint.transform.location.y])
vec2wp = waypoint_np - current_pos_np
motion_vec = current_pos_np - past_pos_np
dot = np.dot(vec2wp,motion_vec)
if (dot >=0):
while(self.dist2Waypoint(waypoint) > threshold) :
control_signal = self.controller.run_step(self.vel_ref,waypoint)
self.vehicle.apply_control(control_signal)
self.update_spectator()
def getLeftLaneWaypoints(self, offset = 2*VEHICLE_VEL, separation = 0.3):
current_waypoint = self.world.get_map().get_waypoint(self.vehicle.get_location())
left_lane = current_waypoint.get_left_lane()
self.waypointsList = left_lane.previous(offset)[0].previous_until_lane_start(separation)
def getRightLaneWaypoints(self, offset = 2*VEHICLE_VEL, separation = 0.3):
current_waypoint = self.world.get_map().get_waypoint(self.vehicle.get_location())
right_lane = current_waypoint.get_left_lane()
self.waypointsList = right_lane.next(offset)[0].next_until_lane_end(separation)
def do_left_lane_change(self):
self.getLeftLaneWaypoints()
for i in range(len(self.waypointsList)-1):
self.current_pos = self.vehicle.get_location()
self.go2Waypoint(self.waypointsList[i])
self.past_pos = self.current_pos
self.update_spectator()
def do_right_lane_change(self):
self.getRightLaneWaypoints()
for i in range(len(self.waypointsList)-1)
self.current_pos = self.vehicle.get_location()
self.go2Waypoint(self.waypointsList[i])
self.past_pos = self.current_pos
self.update_spectator()
def update_spectator(self):
new_yaw = math.radians(self.vehicle.get_transform().rotation.yaw)
spectator_transform = self.vehicle.get_transform()
spectator_transform.location += carla.Location(x = -10*math.cos(new_yaw), y= -10*math.sin(new_yaw), z = 5.0)
self.spectator.set_transform(spectator_transform)
self.world.tick()
def is_waypoint_in_direction_of_motion(self,waypoint):
current_pos = self.vehicle.get_location()
def draw_waypoints(self):
for waypoint in self.waypointsList:
self.world.debug.draw_string(waypoint.transform.location, 'O', draw_shadow=False,
color=carla.Color(r=255, g=0, b=0), life_time=10.0,
persistent_lines=True)
dt = 1.0 / 20.0
args_lateral_dict = {'K_P': 1.95, 'K_I': 0.05, 'K_D': 0.2, 'dt': dt}
args_longitudinal_dict = {'K_P': 1.0, 'K_I': 0.05, 'K_D': 0, 'dt': dt}
offset = 0
VEHICLE_VEL = 10
actorList = []
try:
client = carla.Client("localhost",2000)
client.set_timeout(10.0)
world = client.load_world("Town02")
spectator = world.get_spectator()
actorList.append(spectator)
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 1/20
world.apply_settings(settings)
blueprint_library = world.get_blueprint_library()
vehicle_bp = blueprint_library.filter("cybertruck")[0]
player = Player(world, vehicle_bp)
actorList.append(player.vehicle)
actorList.append(player.spectator)
while(True):
player.update_spectator()
manoeuver = input("Enter manoeuver: ")
if ( manoeuver == "l"): #Perform left lane change
player.do_left_lane_change()
elif (manoeuver == "r"): #Perform right lane change
player.do_right_lane_change()
elif (manoeuver == "d"): #Just draws the waypoints for debugging purpose
player.getLeftLaneWaypoints()
player.draw_waypoints()
finally:
print("Destroying actors")
client.apply_batch([carla.command.DestroyActor(x) for x in actorList])

creating fishet grid using python

I'm trying to create a fishnet grid to aggregate some geospatial data. I am using the following code from the GDAL/OGR Python cookbook however it returns only one polygon object which is basically a huge rectangle. Please let me know what I'm doing wrong.
source: https://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html#create-fishnet-grid
import os, sys
import ogr
from math import ceil
def main(outputGridfn,xmin,xmax,ymin,ymax,gridHeight,gridWidth):
# convert sys.argv to float
xmin = float(xmin)
xmax = float(xmax)
ymin = float(ymin)
ymax = float(ymax)
gridWidth = float(gridWidth)
gridHeight = float(gridHeight)
# get rows
rows = ceil((ymax-ymin)/gridHeight)
# get columns
cols = ceil((xmax-xmin)/gridWidth)
# start grid cell envelope
ringXleftOrigin = xmin
ringXrightOrigin = xmin + gridWidth
ringYtopOrigin = ymax
ringYbottomOrigin = ymax-gridHeight
# create output file
outDriver = ogr.GetDriverByName('ESRI Shapefile')
if os.path.exists(outputGridfn):
os.remove(outputGridfn)
outDataSource = outDriver.CreateDataSource(outputGridfn)
outLayer = outDataSource.CreateLayer(outputGridfn,geom_type=ogr.wkbPolygon )
featureDefn = outLayer.GetLayerDefn()
# create grid cells
countcols = 0
while countcols < cols:
countcols += 1
# reset envelope for rows
ringYtop = ringYtopOrigin
ringYbottom =ringYbottomOrigin
countrows = 0
while countrows < rows:
countrows += 1
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(ringXleftOrigin, ringYtop)
ring.AddPoint(ringXrightOrigin, ringYtop)
ring.AddPoint(ringXrightOrigin, ringYbottom)
ring.AddPoint(ringXleftOrigin, ringYbottom)
ring.AddPoint(ringXleftOrigin, ringYtop)
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)
# add new geom to layer
outFeature = ogr.Feature(featureDefn)
outFeature.SetGeometry(poly)
outLayer.CreateFeature(outFeature)
outFeature = None
# new envelope for next poly
ringYtop = ringYtop - gridHeight
ringYbottom = ringYbottom - gridHeight
# new envelope for next poly
ringXleftOrigin = ringXleftOrigin + gridWidth
ringXrightOrigin = ringXrightOrigin + gridWidth
# Save and close DataSources
outDataSource = None
if __name__ == "__main__":
#
# example run : $ python grid.py <full-path><output-shapefile-name>.shp xmin xmax ymin ymax gridHeight gridWidth
#
if len( sys.argv ) != 8:
print "[ ERROR ] you must supply seven arguments: output-shapefile-name.shp xmin xmax ymin ymax gridHeight gridWidth"
sys.exit( 1 )
main( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7] )
Output:
The code look good to me, perhaps it's a "flushing" issue. Try also closing the layer by setting it to None:
outLayer = None
The code you are using is quite elaborate, a nice demonstration of how OGR works, but you could simply it quite a bit. Consider the example below:
Define the grid and output:
# settings
output_shp = r'D:\tmp_grid_v5.shp'
drv = ogr.GetDriverByName('ESRI Shapefile')
if os.path.exists(output_shp):
# DeleteDataSource will delete related files, compared to os.remove
drv.DeleteDataSource(output_shp)
# grid definition
# extent
ulx, uly, lrx, lry = -180, 90, 180, -90
# resolution 1 degree grid
xres = 1
yres = -1
# half the resolution
dx = xres/2
dy = yres/2
Calculate the center coordinates of each polygon. Using Numpy meshgrid is convenient but calculates all at once. If memory is an issue you could do this one by one.
# center coordinates
xx, yy = np.meshgrid(
np.arange(ulx+dx, lrx+dx, xres),
np.arange(uly+dy, lry+dy, yres),
)
Initialize the output shapefile:
ds = drv.CreateDataSource(output_shp)
lyr = ds.CreateLayer(output_shp, geom_type=ogr.wkbPolygon)
fdefn = lyr.GetLayerDefn()
Loop over each center coordinate and add the polygon to the output:
for x,y in zip(xx.ravel(), yy.ravel()):
poly_wkt = f'POLYGON (({x-dx} {y-dy}, {x+dx} {y-dy}, {x+dx} {y+dy}, {x-dx} {y+dy}, {x-dx} {y-dy}))'
ft = ogr.Feature(fdefn)
ft.SetGeometry(ogr.CreateGeometryFromWkt(poly_wkt))
lyr.CreateFeature(ft)
ft = None
Close the output
lyr = None
ds = None

Problems at getting texture's color at a given point

I'm trying to get the color of a texture at an u v coordinate in relation with the vertex of a poly. The issue that I'm having is that every coordinate that I get result in the same color even if it is not painted that way.
I've been trying to place a texture and paint it later, then get the color of each vertex in a simple plane. What I could see around is more or less what I already have, polyListComponentConversion and colorAtPoint with the uv coordinates got.
The points that I get are [0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0], and the color is always the same which is painted in one of the corners.
If instead using these I try hardcoding another value (like [.5, .5]) then I get another color which seems accurate.
What I do is:
#Create and place the texture files into the poly
def createShadingEngine(vName):
vNewShadingGroup = mc.sets(name = '{0}_SG'.format(vName), empty = True, renderable = True, noSurfaceShader = True)
vNewMaterial = mc.shadingNode('lambert', name = '{0}_mat'.format(vName), asShader = True)
mc.connectAttr('{0}.outColor'.format(vNewMaterial), '{0}.surfaceShader'.format(vNewShadingGroup))
vNewTexture = mc.shadingNode('file', name = '{0}_file'.format(vName), asTexture = True)
vNewUtility = mc.shadingNode('place2dTexture', name = '{0}_tex'.format(vName), asUtility = True)
mc.connectAttr('{0}.outColor'.format(vNewTexture), '{0}.color'.format(vNewMaterial))
vConnectAttr = ['coverage', 'translateFrame', 'rotateFrame', 'mirrorU', 'mirrorV', 'stagger', 'wrapU', 'wrapV',
'repeatUV', 'offset', 'rotateUV', 'noiseUV', 'vertexUvOne', 'vertexUvTwo', 'vertexUvThree', 'vertexCameraOne']
for vAttr in vConnectAttr:
mc.connectAttr('{0}.{1}'.format(vNewUtility, vAttr), '{0}.{1}'.format(vNewTexture, vAttr))
mc.connectAttr('{0}.outUV'.format(vNewUtility), '{0}.uv'.format(vNewTexture))
mc.connectAttr('{0}.outUvFilterSize'.format(vNewUtility), '{0}.uvFilterSize'.format(vNewTexture))
return vNewShadingGroup
#Get the map points for the poly
def getPolyMap(vPoly):
vPoints = []
if mc.objExists(vPoly):
vShape = mc.listRelatives('pPlane1', children = True, fullPath = True, shapes = True)[0]
vEngine = mc.listConnections(vShape, type = 'shadingEngine')
vMaterials = mc.ls(mc.listConnections(vEngine), materials = True)
vTextureFiles = mc.listConnections(vMaterials, type = 'file')
if vTextureFiles :
vMapPoints = mc.polyListComponentConversion('{0}.vtx[*]'.format(vPoly), fv = True, tuv = True)
vMapPoints = mc.ls(vMapPoints, flatten = True)
for vPoint in vMapPoints:
vCoord = mc.polyEditUV(vPoint, q = True)
print vPoint, vCoord
vPoints.append(vCoord)
return vPoints
#Get the color at those points
def getColorAtPointUV(vPoly, vUVPoint = [0, 0]):
vColor = ''
vShape = mc.listRelatives('pPlane1', children = True, fullPath = True, shapes = True)[0]
vEngine = mc.listConnections(vShape, type = 'shadingEngine')
vMaterials = mc.ls(mc.listConnections(vEngine), materials = True)
vTextureFiles = mc.listConnections(vMaterials, type = 'file')
if vTextureFiles and len(vUVPoint) == 2:
vColor = mc.colorAtPoint('{0}.outColor'.format(vTextureFiles ), o = 'RGB', u = vUVPoint[0], v = vUVPoint[1])
return vColor
#With those functions I execute:
vShape = mc.listRelatives('pPlane1', children = True, fullPath = True, shapes = True)[0]
vEngine = mc.listConnections(vShape, type = 'shadingEngine')
vMaterials = mc.ls(mc.listConnections(vEngine), materials = True)
vTextureFiles = mc.listConnections(vMaterials, type = 'file')
cv = getPolyMap('pPlane1')
for cc in cv:
print cc, mc.colorAtPoint(vTextureFiles, o = 'RGB', u = cc[0], v = cc[1])
The result I get from that is:
[0.0, 0.0] [0.00784313678741455, 0.9921568036079407, 0.00784313678741455]
[1.0, 0.0] [0.00784313678741455, 0.9921568036079407, 0.00784313678741455]
[0.0, 1.0] [0.00784313678741455, 0.9921568036079407, 0.00784313678741455]
[1.0, 1.0] [0.00784313678741455, 0.9921568036079407, 0.00784313678741455]
Every corner of the uv prints green, even if only a corner of it is of that color.
On the other hand, if I force it with u = .5, v = .5 the result is the correct one (default grey [0.5019607543945312, 0.5019607543945312, 0.5019607543945312])
Can't post images, but is a grey square with a green dot covering the upper right corner).

subplot with plotly with multiple traces

i am trying to create subplots for the following plots:
the code i used for the the plots are :
radius_mean1 = df[df['diagnosis']==1]['radius_mean']
radius_mean0 = df[df['diagnosis']==0]['radius_mean']
trace_rm1 = go.Histogram(x = radius_mean1, opacity = 0.75, name = 'malignant')
trace_rm2 = go.Histogram(x = radius_mean0, opacity = 0.75, name = 'benign')
data2 = [trace_rm1,trace_rm2]
layout2 = go.Layout(barmode = 'overlay', title = 'radius mean')
fig2 = go.Figure(data=data2, layout=layout2)
py.iplot(fig2)
and similar for the other plot
now i use the following code i found to create subplots:
fig.append_trace(fig1['data'][1], 1, 1)
fig.append_trace(fig2['data'][0], 2, 1)
py.iplot(fig)
and i get this :
how do i add both benign and malignant results to the subplots ?
i cant seem to edit the [0] or [ 1] to show both ie have the first 2 plots exactly into my subplot showing both malignant and benign and not just one or the other.
The data here is not complete, so I using some demo data to present.
import numpy as np
import plotly.graph_objs as go
import plotly
a = np.random.normal(0,1,100)
b = np.random.normal(-2,5,100)
c = np.random.normal(0,1,100)
d = np.random.normal(-2,5,100)
fig = plotly.tools.make_subplots(rows=2,cols=1)
trace_rm1 = go.Histogram(x = a, opacity = 0.75, name = 'malignant')
trace_rm2 = go.Histogram(x = b, opacity = 0.75, name = 'benign')
fig.append_trace(go.Histogram(x = a, opacity = 0.75, name = 'benign'),1,1)
fig.append_trace(go.Histogram(x = b, opacity = 0.75, name = 'malignant'),1,1)
fig.append_trace(go.Histogram(x = c, opacity = 0.75, name = 'benign'),2,1)
fig.append_trace(go.Histogram(x = d, opacity = 0.75, name = 'malignant'),2,1)
fig.layout.update(go.Layout(barmode = 'overlay',))
plotly.offline.plot(fig)

Python and matplotlib - Plotting and drawing images inside class methods result in figures that are "not responding"

I have created a class, ParRec, that reads data from Par/Rec-files (binary images -> numpy-arrays), and now I want to add additional methods to the class to increase functionality, such as a method createFigure(self, ind) that would draw an image of the 2D-image at ind in the 3D-stack of images.
However, this doesn't work no matter how I try, I only get empty figures which are "not responding". There is nothing wrong with the data per se, because when I saved the array to outside the python script and did the exact same thing as in the createFigure-method it did work. These are the relevant parts of the code:
import numpy as np
import matplotlib.pyplot as plt
class ParRec():
def __init__(self, filename, equalResolution = True):
"""
This class is used to read and create a ParRec-object, which contains
arrays of parameters and the corresponding image matrix, in a similar way
to the IDL-struct system previously implemented.
Additionally, the class has several methods that can be called later to
simplify calculations, e.g. removePhaseImages and selectSlice.
filename - full pathname to the Par/Rec-files, without .extension
equalResolution - if set to false, ParRec-object collects parameters like
xres and yres in arrays, otherwise they are constants
and all images in the stack are assumed to be of equal
dimensions.
"""
self.slice_number = 0
self.echo_number = 0
self.dynamic_scan_number = 0
self.cardiac_phase_number = 0
self.image_type_mr = 0
self.scanning_sequence = 0
self.index_in_REC_file = 0 # (in images)
self.image_pixel_size = 0 # (in bits)
self.scan_percentage = 0
self.recon_resolution = 0 # (x y)
self.rescale_intercept = 0
self.rescale_slope = 0
self.scale_slope = 0
self.window_center = 0
self.window_width = 0
self.image_angulation = 0 # (ap,fh,rl in degrees)
self.image_offcentre = 0 # (3*float)
self.slice_thickness = 0 # (in mm)
self.slice_gap = 0 # (in mm)
self.image_display_orientation = 0
self.slice_orientation = 0 # (TRA/SAG/COR) = (1/2/3)
self.fmri_status_indication = 0
self.image_type_ed_es = 0 # (end diast/end syst)
self.pixel_spacing = 0 # (x y) (in mm)
self.echo_time = 0
self.dyn_scan_begin_time = 0
self.trigger_time = 0
self.diffusion_b_factor = 0
self.number_of_averages = 0
self.image_flip_angle = 0 # (in degrees)
self.cardiac_frequency = 0 # (bpm)
self.minimum_RR_interval = 0 # (in ms)
self.maximum_RR_interval = 0 # (in ms)
self.turbo_factor = 0 # (0=no turbo)
self.inversion_delay = 0 # (in ms)
self.diffusion_b_value_number = 0 # (imagekey!)
self.gradient_orientation_number = 0 # (imagekey!)
self.contrast_type = 0
self.diffusion_anisotropy_type = 0
self.diffusion = 0 # (ap, fh, rl)
self.label_type = None # (ASL) (imagekey!)
self.xres = 0
self.yres = 0
self.size = 0
self.equalResolution = equalResolution
# Read ParRec-files
self.readPar(filename)
self.readRec(filename)
# Get number of slices, dynamics, information about phase images etc.
self.getAdditionalData()
def readPar(self,filename)
...
def redRec(self,filename)
...
self.matrix = ...
def createFigure(self, ind):
img = self.matrix[:,:,ind].astype(np.float32)
fig = plt.figure()
plt.imshow(img, cmap = plt.cm.gray)
return fig
if __name__ == '__main__':
filename = '...\filename'
obj = ParRec(filename)
fig = obj.createFigure(0)
plt.show()
Can anybody explain what's going on? That is, why the image-drawing doesn't work when used as a class-method like this, and how to make it work?
EDIT: Inserted the init method, and managed to screw up the indentation a bit, but that is not a problem in the original code.
Best regards,
Mikael

Categories