Set zorder for the labels (vertex_text) in graph_tool - python

I have a case in which vertex_text is hidden behind the one of the vertices (indicated by the red square in the image below). I have drawn this network using graph_tool's circular layout (minimize_nested_blockmodel_dl).
In the graph_tools docs (https://graph-tool.skewed.de/static/doc/draw.html), I did not find any way to set the zorder for the vertex_text.
I wonder if setting zorders for elements is possible in graph_tool. I would like to know if there is any workaround for this, while keeping the plot and the labels as they are i.e. same size, layout and locations.
If this is useful, for reference, here's are the vertex related parameters I used that went into the draw module:
vertex_text=[list of labels],
vertex_fill_color=[list of colors],
valpha=1,
vertex_size=10,
vertex_pen_width=0,
vertex_text_position=-2,

This can be done using the vorder parameter, which determines the relative order with which nodes and their labels are drawn.

Related

How to unlink axes for Panel objects in Holoviews

I am trying to create two graphs that depend on the same slider values. Unfortunately, when I try to move the graph of one, I move the axes of the other. In addition, the xlims are linked when they are not supposed to, even when they are set explicitly. This is causing my plotted curves to be off the graph. I attached pictures for reference. How do I make it so the graphs are independent?
So, I found out the answer. There's a keyword "shared_axes" that you can set to be False. Put this in .opts(shared_axes=False) for both plots.

How to set color limits property of edgecolor for a patchcollection (python, matplotlib)

I am plotting volumetric distributions with x, y and z axis (particle size, particle shape, volume (%) (z-axis as colour scale). Upon exporting the figure as svg, white space appears between the plotted rectangles. I therefore tried setting the edgecolor of the patchcollection. This works, however, the edgecolors have different clim and therefore the color of the edges differs from the patches themselves (see example figure). Code for setting the patchcollection:
p = PatchCollection(rects,cmap=matplotlib.cm.viridis)
colors = curem # colour of rectangles based on volume of the size-shape bins of curem
p.set_array(np.array(colors))
p.set_edgecolor(matplotlib.cm.viridis(np.array(colors)))
p.set_clim([0, math.ceil(np.max(ems[ii]))]) # set maximum to max Rsqclass rounded up to next 1/5th
axs[zz].add_collection(p) # add all the rectangles to the figure
So how do I go about setting the color limits for the edges? Thanks in advance, Hans
After trying out several of Diziet Asahi's proposed solutions, I found that for this specific case, the following works:
p.set_edgecolor('face') # edgecolor equal to facecolor
p.set_linewidth(0.5)
The edgecolor is now equal to the facecolor. A small linewidth (e.g. the suggested 0.000000000001) does not work. White lines still appear when the svg is viewed in microsoft internet explorer or inkscape. A linewidth of 0.5 gets rid of the wite space. However, it should be noted that the required linewidth depends on the level of zoom. E.g., at 400% zoom a linewidth of 0.1 is sufficient. At 30% zoom a linewidth of 0.5 is still insufficient.
One further note: the above solution is specific to svg vector graphics. When stored as .pdf, the solution that Diziet linked to actually does work (set linewidth to an infinitesimally small value).
There seem to be a general problem with showing undesired linestrokes with vector backends, as per this issue on matplotlib's github
A proposed temporary fix is to use very small, but non-zero linewidths:
either pass linewidths=0.000000000001 to the constructor
p = PatchCollection(rects,cmap=matplotlib.cm.viridis, linewidths=0.000000000001)
or use
p.set_linewidth(0.000000000001)

Reuse result of stochastic python-igraph layout for future plotting

I can successfully draw a nice network using the kk layout. Unfortunately, as kk is a stochastic layout, it looks different every time I plot it.
Is there a way to plot it twice with the same vertex and node arrangement but varying the visual style? I would like to visualize changes by changing the vertex colors and showing both plots side-by-side. Of course, in the future I might be interested in modifying edges too but this is not an issue right now.
I'm completely fine with the fact that the layout changes for every run of my programm, it should just plot it consistently within one run.
I can plot it twice if I save the resulting SVG but of course modyfining the underlying graph would be more elegant than just tweaking the raw SVG.
This plots the same layout twice but only as SVG:
s = cairo.SVGSurface(None, 800, 800)
model = ig.plot(g, **visual_style,
vertex_label=[label_for_title(vertex[1]['title']) for vertex in enumerate(g.vs)],
edge_color=[color_for_rating(edge[1]['rating']) for edge in enumerate(g.es)],
target=s,
mark_groups=action_systems)._repr_svg_()
display(SVG(model))
display(SVG(model))
Yes, there is, because igraph lets you store the layout of the vertices as an object: my_layout = g.layout('kk').
So you can plot your graph g multiple times with the same layout:
my_layout = g.layout('kk')
igraph.plot(g,layout=my_layout)
#now change g and/or the visual style
g.delete_edges([0,3,4])
igraph.plot(g,layout=my_layout,vertex_color=['blue' for _ in g.vs])
The new plotted graph will have the same vertex positions but now a few edges will be gone and all the vertices will be blue, naturally.

Matplotlib savefig pdf doesn't display some polygons

I'm making a relatively simple plot that seemed to work fine. I have a number of line segments, and each defines an area. I'm using polygons for the filled areas using plot.Polygon and ax.add_patch.
When I save to .png, everything works fine. So, I turn to pdf for the final image. I manually set things like fontsize, figsize and dpi, so there should be no problem.
Sadly, 2 out of the four Polygons in the current picture are not displayed in the pdf. Which is strange; the previous two images (other datasets) did act correctly. I've played around a bit with zorder and alpha on the Polygons but to no avail.
My google search did not turn up anything; it mentioned the dpi being different if you haven't set it manually, but this is no problem. Beyond that, I could find no clear reasons.
My sincere thanks,
Daimonie
Okay, so I've found the problem.
Let's first denote the method I use to add the polygons, just for clarity. The points $(x,y)$ that define the vertices are called vertices. The polygon is made as:
first_polygon = plt.Polygon(vertices, zorder=.1, facecolor=colours[colour_index], alpha=fill_opacity)
Next, I add it to the figure:
ax.add_patch(first_polygon)
So why didn't it display some polygons? I cannot be sure of the reason, but the issue resolved when I redefined the polygons. The two polygons that didn't display were bound by three lines. The first polygon was bound by y0, y1, y2 and the 'frame' of the figure. Because I was still scaling the figure, I had put the point that bound it by the 'frame' as $(100, -100)$. When I changed that to $(min_x, min_y)$ it suddenly displayed properly.

How to set the physical length from an axis in matplotlib?

Is there a command to set the length of an axis? I do not mean the range! Independently from the values, the range from the axis or other factors, I want to set its length. How can I do that?
Something like plt.yaxislenght(20)?
I'm not sure of a specific way to set an axis length of axes generated by e.g. plt.subplots. You can use ax.set_aspect(num), but this adjusts the aspect ratio, and therefore will change both axes in a dependent way.
You can however use ax = plt.axes([left,bottom,width,height]) to add individual subplots in whatever positions you like. This should allow you to achieve what you want, but will be tedious because you need to place each subplot manually.
What you want to do is tricky due to the way that mpl works underneath. Most of the artist are specified in units that are not on-screen units (data, axes, or figure space: see transfrom tutorial). This gives you a good deal of power/flexibility as most of the time you want to work in one of the relative sets of coordinates, however the cost is if you want to set 'absolute' sizes of things you end up having to do it indirectly.
If you want you axis to be a fixed length (in display units) between figures, then you need to control the size of you axes (in figure units) by hand (via fig.add_axes) and then use fig.set_size_inches to set the size of your over-all figure. By tweaking these values you can get what you want.

Categories