Matplotlib Save color from cmap - python

Been unable to figure this one out so was hoping someone here could point me in the right direction...
I am basically trying to store the color that was used from my colormap such that I can use it later on in the code.
color_map = cm.get_cmap('Spectral')
for grp,frame in x.groupby('time'):
ax.scatter(x, y, cmap=color_map)
<other code>
ax.axvline(x=magic_number, color=<???>)
plt.show()
Pretty much I want to use the same color from my map in the for loop. I believe this is pretty simple to do but I cant seem to find the right combination of things to search for to get the answer.

I couldn't completely understand what you are trying to achieve. I'm not sure that below will be helpful.... (sadly)
your code should be something like this:
ax.axvline(x=magic_number, color=color_map(float(magic_number)/float(max_magix_number) ) )
It works quite simple float(magic_number)/float(max_magix_number) gives a float number in the range from zero to one. color_map(scaled number) returns required color as a tuple of R,G,B and transparancy....
>>> c = get_cmap('Spectral')
>>> c(0.5)
(0.998077662437524, 0.9992310649750096, 0.7460207612456747, 1.0)
>>>

Related

How to change titles (facet_col )in imshow (plotly)

I want to plot several images with imshow from plotly and give each image a title.
My code is
fig = px.imshow(numpy.array(img1,img2), color_continuous_scale='gray', facet_col=0, labels={'facet_col' : 'status'})
fig.update_xaxes(showticklabels=False).update_yaxes(showticklabels=False)
fig.show()
and the result looks like
However, I would like to replace status=0 with original and status=1 with clean. Is there an easy way to achieve this result?
Thanks for any help.
I solved my problem by
fig = px.imshow(
numpy.array(img1,img2),
color_continuous_scale='gray',
facet_col=0
)
fig.update_xaxes(showticklabels=False).update_yaxes(showticklabels=False)
for i, label in enumerate(['orignal', 'clean']):
fig.layout.annotations[i]['text'] = label
fig.show()
It would be nice, if there would be a shorter way e.g. passing the list of labels directly to the imshow command. However, I did not find any possibility to do that.
I appreciate the answer by #DerJFK, however, it won't support multirows.
This trick will fix the problem:
item_map={f'{i}':key for i, key in enumerate(['orignal', 'clean'])}
fig.for_each_annotation(lambda a: a.update(text=item_map[a.text.split("=")[1]]))
According to the docs, adding parameter 'x' with a list of names should solve it.
fig = px.imshow(numpy.array(img1,img2),
color_continuous_scale='gray',
facet_col=0,
labels={'facet_col' : 'status'},
x=['Orginal', 'Clean'])
fig.update_xaxes(showticklabels=False).update_yaxes(showticklabels=False)
fig.show()

How to Order Coordinates in Matplotlib (xticks and yticks)

Alright, so I was working on a simple program to just pull coordinates out of a text pad and then graph what was in the text pad on a graph. I thought it would be pretty simple, but I am VERY new to matplotlib, so I still don't fully understand. I got most of the code done correctly, but the only thing that is not working is that when I put the values in the graph, they come all out of order. I want to order the xticks and yticks so that it actually looks like a real line graph you'd see in math, so you can see how the lower coordinates lower than the higher coordinates, and vice versa. Here is my code:
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
def split(word):
return list(word)
fileIWant = open('C:/Users/JustA/Desktop/Python Shenanigans/Converting Coordinates in a .txt to a Graph/Coordinates.txt', 'r');
stopwords = ['\n']
array = fileIWant.readlines()
array = [array.replace('\n', '') for array in array if array not in stopwords]
fileIWant.close()
editFile = open('C:/Users/JustA/Desktop/Python Shenanigans/Converting Coordinates in a .txt to a Graph/Coordinates.txt', 'w')
array_length = len(array)
x = []
y = []
for i in range(array_length):
dataSplit = array[i].split()
getCoordinateX = dataSplit[1]
getCoordinateY = dataSplit[3]
x.append(getCoordinateX)
y.append(getCoordinateY)
plt.scatter(x, y)
plt.plot(x, y) #Add this line in if you want to show lines.
plt.title('Your Coordinate Graph')
plt.xlabel('X Coordinates')
plt.ylabel('Y Coordinates')
#plt.xticks([-100,-80,-60,-40,-20,0,20,40,60,80,100])
#plt.yticks([-100,-80,-60,-40,-20,0,20,40,60,80,100])
plt.show()
editFile.close()
I commented out what I put for the ticks, because it was not working at all. With those commented out, it looks okay, but it is very confusing. I think it just puts them in the order they are at in the .txt, when I want them to order themselves in the code. Here is what it is outputting right now:
Sorry if this is so simple that it has never been asked before, like I said, very new to matplotlib, and numpy if I have to use that at all. I imported it because I thought I may have to, but I don't think I really used it as of yet. Also, I am going to rewrite the coordinates into the graph in order, but I think I can do that myself later.
The problem is that your coordinates are strings, which means matplotlib is just plotting strings against strings ("categorical" axis labels). To fix, you simply have to convert your strings to numbers, e.g. x.append(int(getCoordinateX)).
Note that you also don't have to put plt.scatter/plt.plot in the loop - you only have to call one of those once on the full array. That'll probably make things a little faster too.

How to make Plt.plot show my parabolic line in python?

Maybe this will be duplicate question but I couldn't find any solution for this.
Normally what I coded should show me a curved line in python. But with this code I cant see it. Is there a problem with my code or pycharm ? This code only shows me an empty graphic with the correct axes.
And I did adding "ro" in plt.plot(at[i], st, "ro"). This showed me the spots on the graph but what I want to see the complete line.
at = [0,1,2,3,4,5,6]
for i in range(len(at)):
st = at[i]**2
plt.plot(at[i], st)
plt.show()
This is how you would normally do this:
import numpy as np
import matplotlib.pyplot as plt
at = np.array([0,1,2,3,4,5,6])
at2 = at ** 2
plt.plot(at,at2)
plt.show()
you can use something like plt.plot(at,at2, c='red', marker='o') to see the spots.
for detailed explanation please read the documentation.
Maybe rather calculate the to be plotted values entirely before plotting.
at = [0,1,2,3,4,5,6]
y = [xi**2 for xi in at]
plt.plot(at, y)
Or do it alternatively with a function
from math import pow
at = [0,1,2,3,4,5,6]
def parabolic(x):
return [pow(xi,2) for xi in x]
plt.plot(at, parabolic(at))
both return the following plot:
the other answers give fixes for your question, but don't tell you why your code is not working.
the reason for not "seeing anything" is that plt.plot(at[i], st) was trying to draw lines between the points you give it. but because you were only ever giving it single values it didn't have anything to draw lines between. as a result, nothing appeared on the plot
when you changed to call plt.plot(at[i], st, 'ro') you're telling it to draw single circles at points and these don't go between points so would appear
the other answers showed you how to pass multiple values to plot and hence matplotlib could draw lines between these values.
one of your comments says "its not parabolic still" and this is because matplotlib isn't a symbolic plotting library. you just give it numeric values and it draws these onto the output device. sympy is a library for doing symbolic computation and supports plotting, e.g:
from sympy import symbols, plot
x = symbols('x')
plot(x**2, (x, 0, 6))
does the right thing for me. the current release (1.4) doesn't handle discontinuities, but this will be fixed in the next release

Python plot fix size

thanks for reading my question !
I created plot using Pyplot, this is my data :
Length of "point" array is : 114745
Length of "id_item" array is : 114745
Length of "sessions" array is : 92128
And this is my code :
point = []
id_item = []
sessions = [] # temp_dict.keys()
for item in cursor_fromCompanyDB:
sessions.append(item['sessionId'])
for object_item in item['objects']:
point.append(object_item['point'])
id_item.append(object_item['id'])
plt.figure()
plt.title('Scatter Point and Id of SessionId', fontsize=20)
plt.xlabel('point', fontsize=15)
plt.ylabel('Item', fontsize=15)
plt.scatter(point, id_item, marker = 'o')
plt.autoscale(enable=True, axis=u'both', tight=False)
for label, x, y in zip(sessions, point, id_item):
plt.annotate(label, xy = (x, y))
plt.show()
And this is result :
As you can see, values very close and hard to see.
I want value in id_item show full value and values in the center (sessions) easy to see.
Thanks very much to help me.
There are two ways to fix your plot:
Make the plot so large that you have to scroll down pages to see every session ID.
Reduce your data / don't display everything.
Personally, I'd take option 2. At a certain point it becomes impossible or just really ugly to display a certain amount of points, especially with labels assigned to them. You will have to make sacrifices somewhere.
Edit: If you really want to change your figure size, look here for a thread explaining how to do that.

Plotting 2 or more functions in the same graph

I would like to plot 2 curves in the same figure with the following code:
import sympy as syp
x, y = syp.symbols('x, y')
my_function = syp.exp(-(x-2)**2)*syp.exp(-(y-3)**2) + 2*syp.exp(-(x+1)**2)*syp.exp(-(y-1)**2)
gradient_1 = syp.diff(my_function, x)
gradient_2 = syp.diff(my_function, y)
curve_1 = syp.plot_implicit(syp.Eq(gradient_1, 0))
curve_2 = syp.plot_implicit(syp.Eq(gradient_2, 0))
What I see is only the first plot, while I would like to have both the curves in the same picture, maybe also with a grid if possible.
Any ideas?
Note: with matplotlib it's very easy, but I cannot find any specific example for the function syp.plot_implicit
Another, perhaps more efficient way, would be to compute both at the same time using Or
plot_implicit(Or(Eq(gradient_1, 0), Eq(gradient_2, 0)))
It might work if you do:
>>> curve_1.extend(curve_2)
>>> curve_1.show()
However mixing implicit plots might not be implemented yet.
Be aware that your curve_1 and curve_2 are not what sympy considers "single curves" i.e. Series instance, but rather "collections of a number of curves", i.e. Plot instances.
You can also extract the matplotlib objects from curve_1._backend.fig and other _backend attributes.
In conclusion, there is a nice API to do what you want, but probably the methods behind it are not finished yet.
Another way:
curve_1.append(curve_2[0])
curve_1.show()

Categories