How can I adjust the distance in a bipartite pie graph using igraph? - igraph

I am using igraph (R) to draw a bipartite graph with pie shaped vertices.
Simple example:
library(igraph)
inc <- matrix(sample(0:1, 50, replace = TRUE, prob=c(2,1)), 10, 5)
values <- lapply(1:15, function(x) sample(1:10,3))
g <- graph_from_incidence_matrix(inc)
plot(g, vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(5)),
layout = layout_as_bipartite)
tall graph
I would like to decrease the distance between the upper and lower nodes. If I use asp I get the following
plot(g, vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(5)),
layout = layout_as_bipartite, asp = 0.3)
graph with adjusted aspect ratio
The nodes are not round anymore. This doesn't happen when the vertices are not pie.
How can I adjust the distance without skewing the pie shapes?
Many thanks!

Related

SHAP multiclass summary plot for Deep Explainer

I want to use SHAP summary plot for multiclass classification problem using Deep Explainer. I have 3 classes and for shap_values I got a list of 3 arrays each having (1000,1,24) size. Each array representing a class, I am getting the summary plot for individual class
import shap
background = train_x[np.random.choice(train_x.shape[0], 1000, replace=False)]
explainer = shap.DeepExplainer(model, background)
back= test_x[np.random.choice(test_x.shape[0], 1000, replace=False)]
shap_values = explainer.shap_values(back)
shap.summary_plot(shap_values[0][:,0,:], plot_type = 'bar', feature_names = features)
but when i try to plot all three classes on a single summary plot by this code
shap.summary_plot(shap_values,back_x, plot_type="bar",feature_names = features)
it gives me following error
IndexError: index 12 is out of bounds for axis 0 with size 1
how to plot all the 3 classes on a single summary plot?

Convert “world file” GIS for MapBox GL?

I'm trying to display GIF image with a world file (http://webhelp.esri.com/arcims/9.2/general/topics/author_world_files.htm) on Mapbox gl. The image is displayed but it looks like it was shifted couple of degrees up. The following are the setups I followed to calculate the coordinates
A:0.017971305190311 <- Horizontal Pixel Distribution (deg/width) (A)
D:0.000000000000000 <- X Rotation (D)
B:0.000000000000000 <- Y Rotation (B)
E:-0.017971305190311 <- Vertical Pixel Distribution (deg/height) (E)
C:-127.620375523875420 <- X Coordinate for the center of the top left pixel (C)
F:50.406626367301044 <- Y Coordinate for the center of the top left pixel (F)
Used the following equation to calculate the Lat/Long # each corner
Xn = Ax + By + C
Yn = Dx + Ey + F
[-127.62037552387542,50.406626367301044],
[-66.51793787681802,50.406626367301044],
[-66.51793787681802,21.652538062803444],
[-127.62037552387542,21.652538062803444]
The Image documentation state that it was created using standard geographic projection referenced to North American Datum 1983 (NAD83). Is there any other steps needed to be done to display the image correctly on the map ?
Thanks

plotting maps using OSM or other shapefiles and matplotloib for standardized report

We are developing a standardized report for our activities. The last graph I need is to display the geographic area of the activities (there are close to 100 locations).
The output for these reports is PDF letter or A4 size
The report is a mplotlib figure, where:
fig = plt.figure(figsize=(8.5, 11))
rect0 = 0, .7,, 0.18, 0.3
rect1 = .3, .7, .18, .3
rect2 = .8, .29, .2, .7
rect3 = 0, 0, .8, .4
ax1 = fig.add_axes(rect0)
ax2 = fig.add_axes(rect1)
ax3 = fig.add_axes(rect2)
ax4 = fig.add_axes(rect3)
The contents and layout for axes 1-3 are settled and work great. However ax4 is where the map contents would be displayed (ideally).
I was hoping to do something like this:
map1 = Basemap(llcrnrlon=6.819087, llcrnrlat=46.368452, urcrnrlon=6.963978,
urcrnrlat=46.482906, resolution = 'h', projection='tmerc',
lon_0=6.88, lat_0=46.42, ax=4)
map1.readshapefile('a valid shape file that works') #<----- this is the sticking point
map1.draw(insert locator coordinates)
plt.savefig(report to be inserted to document)
plt.show()
However I have not been successful in obtaining a shape file that works from open street maps or GIS.
Nor have I identified the correct process to transform the data from openstreetmaps.
Nor have I identified the process to extract that information from the OSM/xml document or the transformed GeoJSON document.
Ideally I would like to grab the bounding box information from openstreetmaps and generate the map directly.
What is the process to get a shapefile that works with the .readshapefile() call?
Or alternatively how do I get the defined map into a Matplotlib axes ?
It might be easiest to use the cartopy.io.img_tiles module, which will automatically pull the OSM tiles for use with cartopy. Using the pre-rendered tiles would negate the trouble of handling and styling individual shapefiles/XML.
See the cartopy docs on using these tiles within cartopy.

pygame draw lifebar with a clipping area

I'd like to draw a lifebar with pygame by using a clipping area (limit the area to a half when half of the hitpoints are gone for example.)
But even though the clipping area is correct, I always get the full image.
That's my lifebar class:
class Lifebar():
def __init__(self,x,y,images,owner):
self.x=x
self.y=y
self.images=images
self.owner=owner
self.owner.world.game.addGUI(self)
self.inter=False
def getValues(self):
value1 = 1.0 * self.owner.hitpoints
value2 = 1.0 * self.owner.maxhitpoints
return [value1,value2]
def render(self,surface):
rendervalues = self.getValues()
maxwidth = self.images[0].get_width()
ratio = rendervalues[0] / rendervalues[1]
actwidth = int(round(maxwidth * ratio))
surface.blit(self.images[0],(self.x,self.y))
surface.set_clip(self.x, 0, (self.x+actwidth), 1080)
surface.blit(self.images[1],(self.x,self.y))
self.owner.world.game.setclipDefault()
surface.blit(self.images[2],(self.x,self.y))
I checked that the hitpoints weren't full and that the clipping area was limited in x direction. (get_clip())
I don't know if I misunderstood how set_clip() works because I only used it for the whole screen before(objects that were partially out of the screen)
The .set_clip() method of a pygame.Surface object sets the area in which any other surfaces will be drawn into when you call .blit(). This means that the passed rectangle defines a new point of origin on the destination surface as well as the size of the area which will be updated.
To cut out a specific area of an image and draw it onto a surface you could pass an optional rectangle as third parameter to the .blit() method:
surface.blit(source_image, #source image (surface) which you want to cut out
(destination_x, destination_y), #coordinates on the destination surface
(x_coordinate, y_coordinate, width, height)) #"cut out"-rect
I hope this helps you a little bit :)

Need some advice about how bitblit works

I am creating my first game ever using pygame and I've found that in order to animate things the most popular method is to use bit blit.
However I have a few questions regarding this:
From what I understood, when you use bit blit you have to "redraw" on the screen every single object that was present before in order for it to work correctly. Is this correct?
If so... I am drawing a "scene" of buildings using rects (rectangles) (the buildings each have different colors (randomly geneated), different heights (random) and they also have windows which are of 2 different alternating colors). What would be the best way for my Building class to remember every color it had for the building and its windows so that when i bit blit the building doesn't get different colors to make it more realistic?
You could have a simple Building class:
class Building:
def __init__(self, x, y, w, h, color):
self.x = x
self.y = y
self.w = w
self.h = h
self.color = color
def draw(self):
// code for drawing the rect at self.x,self.y
// which is self.w wide and self.h high with self.color here
Concerning the windows, you could specify each one in a list like [(x, y, w, h)] for each building or simply make a building class that looks like this:
class Building:
def __init__(self, x, y, w, h, color, wx, wy):
self.x = x
self.y = y
self.w = w
self.h = h
self.color = color
self.wx = wx
self.wy = wy
def draw(self):
// code for drawing the rect at self.x,self.y
// which is w wide and h high with self.color here
// Draw wx windows horizontally and wy windows vertically
for y in range(0, self.wy):
for x in range(0, self.wx):
// draw Window code here
Another approach would be that you "prerender" your buildings into an image an then just display that afterwards(that could also be faster if you have a lot of buildings).
And your gameloop could then look something like this
buildingList = [Building(0, 0, 15, 50, RED), Building(0, 0, 40, 30, BLUE)]
while gameIsRunning:
// Clear screen code here
// Show Building
for b in buildingList:
b.draw()
// More stuff
That is pretty much the most basic approach for drawing anything, you could draw characters this way, keys or even tiles that are supposed to be above you character, e.g. water tiles in a platformer like Tuff. The trees here are also in one big list(ok actually i maintain a smaller list with the trees that are on the 1 1/2 sourrounding screens for performance reasons. there are over 1500 "trees").
EDIT:
In the case of different window colors, there two possible solutions.
Using different window colors per building:
class Building:
def __init__(self, x, y, w, h, color, wx, wy, windowColor):
self.x = x
self.y = y
self.w = w
self.h = h
self.color = color
self.wx = wx
self.wy = wy
self.windowColor = windowColor
def draw(self):
// code for drawing the rect at self.x,self.y
// which is self.w wide and self.h high with self.color here
// Draw wx windows horizontally and wy windows vertically
for y in range(0, self.wy):
for x in range(0, self.wx):
// draw Window code here using self.windowColor
Possibility 2, with different colors per window:
class Building:
def __init__(self, x, y, w, h, color, windows):
self.x = x
self.y = y
self.w = w
self.h = h
self.color = color
self.wx = wx
self.wy = wy
self.windows = windows
def draw(self):
// code for drawing the rect at self.x,self.y
// which is self.w wide and self.h high with self.color here
// Draw all windows
for w in windows:
// draw Window at w[0] as x, w[1] as y with w[2] as color
// Create a building at 0,0 that is 20 wide and 80 high with GRAY color and two windows, one at 2,2 which is yellow and one at 4, 4 that's DARKBLUE.
b = Building(0, 0, 20, 80, GRAY, [(2, 2, YELLOW), (4, 4, DARKBLUE)])
Yes, consider the screen to be like a canvas you paint onto. Once the scene is finished and shown to the viewer, you start the next scene (aka 'frame') by painting over the top of it, replacing everything that was there. Movement is represented by repeatedly painting the same thing at slightly different places. It's much like traditional animation in film - show a series of subtly different pictures to present the illusion of motion. You typically do this several tens of times per second.
It's not just pygame/SDL's bit blit that works this way - pretty much all real time computer graphics for work this way. However some systems may hide this from you and do it under the covers.
For your buildings and their colours, you want what goes to the screen to be a representation of your game objects. You don't want to draw something and then try to 'remember' what you drew. The rendering should just be a view of the objects and never something authoritative. So when you generate these random heights and colours, that would be done long before the drawing phase. Store these values as part of your building objects, probably at creation time. Then when you come to draw the building each frame, all the information you need is right there and will remain consistent each time you draw it.
You may find the answer to your first question here:
http://en.wikipedia.org/wiki/Bit_blit
Yes. You need to use "painter's algorithm" to draw your scene from back to front.
So, for each frame of animation, you'd draw the background first, then the buildings, and then anything in front of the buildings. You don't need to "clear" the screen if the background covers the whole screen.