Adding legend to complex plot made with mpmath - python

I've been using the cplot command from the mpmath library to plot a complex function. It works pretty easily, all I have to do is write cplot(G_fit, [0.001, v_max], [-v_max, v_max], points = 100000) and I get a fairly smooth graph of my function G_fit over 0.001 < Re(z) < v_max and -v_max < Im(y) < v_max. There are two problems though:
How do I add a legend? It says in the documentation that the magnitude of the function is represented by brightness and the phase angle is the hue. That's fine, but what are the magnitudes and hues? All I want to do is add a bar beside the graph that goes from black to white and gives numerical values for the magnitudes at those brightnesses.
Is there any way to plot just the magnitudes (ie. just brightness?)
Thanks, and sorry if this is trivial, but I couldn't find anything about this in the documentation.

My own research finds that:
Doesn't look like it.
Redefine your function to return the absolute value of its argument.

Related

Convert point/dot annotation in to gaussian density map

I'm studying this paper: https://papers.nips.cc/paper/2010/file/fe73f687e5bc5280214e0486b273a5f9-Paper.pdf and I'm struggling at the function below:
Basically in an image, each person will be annotated a dot rather than bounding box or segmentation. The paper proposed a way to convert a dot into Gaussian density map, which acts as a ground truth. I have try numpy.random.multivariate_normal but it seems not working.
I am working on a research problem involving density maps. This code assumes you are looping over a list of text files, where each text file has the point annotations (or you are converting from object to point annotations, like I did). It also assumes that you have a list of annotations with (x,y) centre points to work with (after reading/processing said text file).
You can find a good implementation of this here:
https://github.com/CommissarMa/MCNN-pytorch/blob/master/data_preparation/k_nearest_gaussian_kernel.py
The above has some extra code for adaptive kernels.
The below code in context (with a lot more 'fluff') is here:
https://github.com/MattSkiff/cow_flow/blob/master/data_loader.py
Here is the code I used:
# running gaussian filter over points as in crowdcount mcnn
density_map = np.zeros((img_size[1],img_size[0]), dtype=np.float32)
# add points onto basemap
for point in annotations:
base_map = np.zeros((img_size[1], img_size[0]), dtype=np.float32)
# subtract 1 to account for 0 indexing
base_map[int(round(point[1]*img_size[1])-1),
int(round(point[0]*img_size[0])-1)] += 1
density_map += scipy.ndimage.filters.gaussian_filter(base_map, sigma = sigma, mode='constant')
This should create a density map that does what you want. Using 'imshow' on an ax object from matplotlib (e.g. ax.imshow(density,cmap='hot',interpolation='nearest') should produce a density map like so (I've added the aerial image to indicate what is being labelled):

Painting numbers used as markers in different colors in matplotlib

I want to represent a dataset of dots, each dot having an x and y coordinate and a single-digit value, and each of the values should be represented by a particular color. What I managed to do is creating sth like that, which looks nice enough:
# x, y and digits are one-dimensional np.arrays of the same shape
plt.scatter(x, y, marker='o', c=digits)
#random colormap
plt.viridis()
Now I want to represent digits themselves instead of just colored dots. As I understand it, marker-argument cannot be an array so I decided that sth like that would work:
for i in range(len(digits)):
plt.scatter(x[i], y[i], c=digits[i], marker=('${}$'.format(digits[i])))
Which almost did, but 'c=digits[i]' doesn't seem to work because a digit doesn't actually encode any particular color. I think (correct me if I'm wrong) that the first code works, because python somehow automatically understands that by c=digits I didn't mean any actual color but wanted to differentiate between two dots.
So the question is:
What is the easiest thing I can do in the second case to indicate the colors of the digits without stating them directly but using a default colormap? (ideally I would like to get sth identical to what first code does, but with digits instead of dots)
It seems I have found a solution, so in case sb has a similar question:
cmap = plt.cm.get_cmap('name_of_demanded_colormap', neededColorsNum).colors
for i in range(len(digits)):
plt.scatter(x[i], y[i], \\
c=np.array([cmap[digits[i]]]), \\
marker=('${}$'.format(digits[i])))
Some "explanations":
- cm is an object needed for gods know what reason;
get_cmap is the method which creates the specified color map, which is unexpectedly not an array but another gods know what object;
colors is the method of color map which finally creates sth to work with, a matrix with rows representing colors;
the code is so natural, jupyter demands to make the color-row two-dimensional, because some misinterpretation possibility.
Whatever complaints, works as intended, so good enough.

Venn3: How to reposition circles and labels?

I have made a three way venn diagram. I have three issues with it that I can't seem to solve.
What is the code to move the circle labels (i.e."Set1","Set2","Set3") because right now one is too far away from the circle.
What is the code to make the circles be three equal sizes/change the circle size?
What is the code to move the circles around the plot. Right now, set2 is within set3 (but coloured differently), I would like the diagram to look more like the "standard" way of showing a venn diagram (i.e. 3 separate circles with some overlap in the middle).
On another note, I found it difficult to find what the commands such as "set_x", "set_alpha" should be; if anyone knew of a manual that would answer by above questions I would appreciate it, I couldn't seem to find one place with all the information I needed.
import sys
import numpy
import scipy
from matplotlib_venn import venn3,venn3_circles
from matplotlib import pyplot as plt
#Build three lists to make 3 way venn diagram with
list_line = lambda x: set([line.strip() for line in open(sys.argv[x])])
set1,set2,set3 = list_line(1),list_line(2),list_line(3)
#Make venn diagram
vd = venn3([set1,set2,set3],set_labels=("Set1","Set2","Set3"))
#Colours: get the HTML codes from the net
vd.get_patch_by_id("100").set_color("#FF8000")
vd.get_patch_by_id("001").set_color("#5858FA")
vd.get_patch_by_id("011").set_color("#01DF3A")
#Move the numbers in the circles
vd.get_label_by_id("100").set_x(-0.55)
vd.get_label_by_id("011").set_x(0.1)
#Strength of color, 2.0 is very strong.
vd.get_patch_by_id("100").set_alpha(0.8)
vd.get_patch_by_id("001").set_alpha(0.6)
vd.get_patch_by_id("011").set_alpha(0.8)
plt.title("Venn Diagram",fontsize=14)
plt.savefig("output",format="pdf")
What is the code to move the circle labels (i.e."Set1","Set2","Set3") because right now one is too far away from the circle.
Something like that:
lbl = vd.get_label_by_id("A")
x, y = lbl.get_position()
lbl.set_position((x+0.1, y-0.2)) # Or whatever
The "A", "B", and "C" are predefined identifiers, denoting the three sets.
What is the code to make the circles be three equal sizes/change the circle size?
If you do not want the circle/region sizes to correspond to your data (not necessarily a good idea), you can get an unweighted ("classical") Venn diagram using the function venn3_unweighted:
from matplotlib_venn import venn3_unweighted
venn3_unweighted(...same parameters you used in venn3...)
You can further cheat and tune the result by providing a subset_areas parameter to venn3_unweighted - this is a seven-element vector specifying the desired relative size of each region. In this case the diagram will be drawn as if the region areas were subset_areas, yet the numbers will be shown from the actual subsets. Try, for example:
venn3_unweighted(...., subset_areas=(10,1,1,1,1,1,1))
What is the code to move the circles around the plot.
The need to "move the circles around" is somewhat unusual - normally you would either want the circles to be positioned so that their intersection sizes correspond to your data, or use the "default" positioning. The functions venn3 and venn3_unweighted cater to those two requirements. Moving circles around arbitrarily is possible, but would require some lower-level coding and I'd advice against that.
I found it difficult to find what the commands such as "set_x", "set_alpha" should be
The object you get when you call v.get_label_by_id is a Matplotlib Text object. You can read about its methods and properties here. The object returned by v.get_patch_by_id is a PathPatch, look here and here for reference.

Python boxplot fails at automatic plot boundaries/limits

I am manually putting a bunch of boxplots in a plot.
The code I am using is this (I am computing mean_, iqr, CL, etc. elsewhere):
A = np.random.random(2)
D = plt.boxplot(A, positions=np.atleast_1d(dist_val), widths=np.min(unique_dists_vals) / 10.) # a simple case with just one variable to boxplot
D['medians'][0].set_ydata(median_)
D['boxes'][0]._xy[[0,1,4], 1] = iqr[0]
D['boxes'][0]._xy[[2,3],1] = iqr[1]
D['whiskers'][0].set_ydata(np.array([iqr[0], CL[0]]))
D['whiskers'][1].set_ydata(np.array([iqr[1], CL[1]]))
D['caps'][0].set_ydata(np.array([CL[0], CL[0]]))
D['caps'][1].set_ydata(np.array([CL[1], CL[1]]))
I do this in a loop, putting one box plot per some location x.
I am not making any changes to the axis limits. The resulting figure looks like this:
what is going on with 1 x-tick?
the limits are just off on both x and y.
This appears to be a bug?
And no, I cannot just manually set the limits etc. since this has to be a completely general code.
What I have tried so far is:
During the loop when I compute the box plots, try keeping track of the largest y value seen so far and the largest x value etc. and then at the end manually set the bound to this. Other issues come up here, however, such as boxes extending beyond the plot etc. and then I manually have to adjust the limits to extend beyond the box width etc.
I have used both "ax.axis('auto')" and "ax.set_autoscale_on(True)" after plotting right before plt.show(), does not work:
While the first item in the list above does technically work (not ideal) I would like to know if there is a generic way to simply say: "done plotting, fix limits" (should automatically be done while plotting I guess?).
Thank you.

Drawing fast lines in pygame

I'm trying to draw fast lines using pygame that aren't rendered directly to the screen. I've got a Python list as large as the number of pixels for the desired resolution, and store integer values corresponding to the number of times that pixel was hit by the line algorithm. Using this, a 2D heat map is built up, so rather than drawing a flat pixel value, pixel values are incremented based on the number of times a line runs through it, and "hot" pixels get brighter colours.
The reason for doing it this way is that we don't know in advance how many of these lines are going to get drawn, and what the maximum number of times any given pixel is going to be hit. Since we'd like to scale the output so that each rendering has the correct maximum and minimum RGB values, we can't just draw to the screen.
Is there a better way to draw these lines than a relatively naive Bresenham's algorithm? Here's the critical part of the drawLine function:
# before the loop, to save repeated multiplications
xm = []
for i in range(resolution[0]):
xm.append(i * resolution[0])
# inside of drawLine, index into the f list, of size resolution[0] * resolution[1]
for x in range(x0, x1 + 1):
if steep:
idx = y + xm[x]
f[idx] += 1
else:
idx = x + xm[y]
f[idx] += 1
The end result is scaled and drawn to the screen based on the maximum value inside of f. For example, if the maximum value is 1000, then you can assume the RGB value of each of the pixels is (f[i] * 255) / 1000.
The profile information says that runtime is dominated by the index lookups into f. I've used previous questions here to prove that these basic lists are faster than numpy arrays or arrays in Python, but for drawing lines like this, it still seems like there's room to improve.
What's a good and fast method for drawing an unknown number of lines to the screen, knowing that you'll be scaling the output in the end to render to the screen? Is there a good way to get rid of the index overhead?
Try Cython or something similar. (If you do, I would be interested in knowing if/how much that helped)
Cython is a programming language to
simplify writing C and C++ extension
modules for the CPython Python
runtime. Strictly speaking, Cython
syntax is a superset of Python syntax
additionally supporting: Direct
calling of C functions, or C++
functions/methods, from Cython code.
Strong typing of Cython variables,
classes, and class attributes as C
types. Cython compiles to C or C++
code rather than Python, and the
result is used as a Python Extension
Module or as a stand-alone application
embedding the CPython runtime.
(http://en.wikipedia.org/wiki/Cython)

Categories