Convert data to colors like scatter plot - python

When using matplotlibs scatter function, it is pretty neat to display data with colors:
data = np.random.random((3, 10))
scatter = plt.scatter(data[0], data[1], c=data[2], cmap='Viridis')
This will automatically map data[2] to a color spectrum that conveys information. Is there a nice way to do that outside of the scatter function?
One reason why Im asking this is because I try to change the colors later. There is a question about it here, but I realised that this will use the normalisation of the old array.
Say I want to change the array that is mapped as colors:
new_colors = 10 * np.random.random(10)
scatter.set_array(new_colors)
This will make almost all points the brightest color instead of choosing an appropriate new range of colors.
Is there a way to circumvent this? Or alternatively can I nicely make a colorarray from this and then pass it to scatter.set_color()

Related

Changing colors in a scatterplot using Matplotlib with python

I am currently taking a Matplotlib class. I was given an image to create the image as a 3D subplot 4 times at 4 different angles. It's a linear plot. As the data changes the plots change colors. As it's an image, I'm not certain where the actual changes start. I don't want an exact answer, just an explanation of how this would work. I have found many methods for doing this for a small list but this has 75 data points and I can't seem to do it without adding 75 entries.
I've also tried to understand cmap but I am confused on it as well.
Also, it needs to done without Seaborn.
This is part of the photo.
I am finding your question a little bit hard to understand. What I think you need is a function to map the input x/y argument onto a colour in your chosen colour map. See the below example:
import numpy as np
import matplotlib.pyplot
def number_to_colour(number, total_number):
return plt.cm.rainbow(np.linspace(0,1.,total_number))[list(number)]
x = np.arange(12)
y = x*-3.
z = x
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c=number_to_colour(x, len(x)))
plt.show()
plt.cm.rainbow(np.linspace(0,1.,total_number)) creates an array of colours of length total_number evenly spaced spaced across the colour map (in this case rainbow). Modifying the indexing of this array (or changing np.linspace to another function with the desired scaling), should give you the colour scaling that you need.

Matplotlib contour map colorbar

I am plotting my data into a contour map. The computations work on the translated values, so I need to put it back to its original value. On the fourth line of the code, is the re-translation process.
However, when I plotted it the colorbar shows the relative values, and just a note of the shift value at the top of the color bar. It is just weird that I checked the matrix values, and it contains the original values.
How can I show the colorbar, with the original values displayed?
fig=plt.figure()
v=np.linspace(-180,180,25)
x,y = np.meshgrid(v,v)
z = np.add(z,-shift)
z = z.reshape(25,25).T
plt.contourf(x,y,z,25)
fig.suptitle(AA(prefix)+' Input Data Contour Map')
plt.xlabel('$\phi$ (deg)')
plt.ylabel('$\psi$ (deg)')
plt.xticks(np.arange(-180, 181, 30))
plt.yticks(np.arange(-180, 181, 30))
plt.colorbar()
UPDATE: I used set_ticklabels() for a temporary fix, where labels is a list of custom labels.
But I am still looking for a better way to solve this problem.
plt.colorbar().set_ticklabels(labels)
updated contour map
Matplotlib doesn't know about your shift variable. It is choosing to plot it that way because the changes you are trying to visualize are 10^(-6) of the background value.
You can force the colorbar to have tick marks at specific locations as they do in this pylab example using:
cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
cbar.ax.set_yticklabels(['< -1', '0', '> 1']) # vertically oriented colorbar
However, doing so will make the scale very difficult to read.

Setting scatter points transparency from data array in matplotlib plot

I am plotting data with matplotlib, I have obtained a scatter plot from two numpy arrays:
ax1.scatter(p_100,tgw_e100,color='m',s=10,label="time 0")
I would like to add information about the eccentricity of each point.
For this purpose I have a third array of the same length of p_100 and tgw_e100, ecc_100 whose items range from 0 to 1.
So I would like to set the transparency of my points using data from ecc_100 creating some sort of shade scale.
I have tried this:
ax1.scatter(p_100,tgw_e100,color='m',alpha = ecc_100,s=10,label="time 0")
But I got this error:
ValueError: setting an array element with a sequence.
According to the documentation alpha can only be a scalar value.
Thus I can't see any other way than looping over all your point one by one.
for x, y, a in zip(p_100, tgw_e100, ecc_100):
ax1.scatter(x, y, color='m',alpha = a, s=10)
I think the labelling will be quite weird though, so you might have to create the legend by hand.
I omitted that from my solution.
I guess a patch to make the alpha keyword argument behave like c and s would be welcome.
Update May 6 2015
According to this issue, changing alpha to accept an array is not going to happen. The bug report suggests to set the colors via an RGBA array to control the alpha value. Which sounds better than my suggestion to plot each point by itself.
c = np.asarray([(0, 0, 1, a) for a in alpha])
scatter(x, y, color=c, edgecolors=c)
Another option is to use a the cmap argument to provide a colormap, and the c argument to provide mappings of how dark/light you want the colors. Check out this question: matplotlib colorbar for scatter
Here's all the matplotlib colormaps: http://matplotlib.org/examples/color/colormaps_reference.html I suggest a sequential colormap like PuRd. If the colors are getting darker in the opposite direction, you can use the "reversed" colormap by appending _r to the name, like PuRd_r.
Try this out:
ax1.scatter(p_100, tgw_e100, c=ecc_100, cmap='PuRd', s=10, label='time 0')
Hope that helps!
Here is a scatter plot of three columns using transparency.
x = sample_df['feature_1']
y = sample_df['feature_2']
#e = {'label_x': 'b', 'label_y': 'r'}
# label_x will be in red, label_y will be in blue
e = {'label_x': np.asarray((1, 0, 0, .1)), 'label_y': np.asarray((0, 0, 1, .1))}
colr = sample_df['label_bc'].map(e)
plt.scatter(x, y, c=colr);

how to scale the histogram plot via matplotlib

You can see there is histogram below.
It is made like
pl.hist(data1,bins=20,color='green',histtype="step",cumulative=-1)
How to scale the histogram?
For example, let the height of the histogram be one third of it is like now.
Besides, it is a way to remove the vertical line at the left?
The matplotlib hist is actually just making calls to some other functions. It is often easier to use these directly allowing you to inspect the data and modify it directly:
# Generate some data
data = np.random.normal(size=1000)
# Generate the histogram data directly
hist, bin_edges = np.histogram(data, bins=10)
# Get the reversed cumulative sum
hist_neg_cumulative = [np.sum(hist[i:]) for i in range(len(hist))]
# Get the cin centres rather than the edges
bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.
# Plot
plt.step(bin_centers, hist_neg_cumulative)
plt.show()
The hist_neg_cumulative is the array of data being plotted. So you can rescale is as you wish before passing it to the plotting function. This also doesn't plot the vertical line.

Displaying matrix-like image with RGB-colored cells in matplotlib

I have a sequence of 3 (or more) colors stored as RGB values (or corresponding hex) and I would like to display them as below:
Following and modifying the suggestions here I was able to get somewhat close, though I am not quite sure I understand how colors are being represented there as a single float. Is there anyway I can convert an RGB/hex representation to whatever matshow() uses? Alternatively, is there a more elegant way of producing the above output?
Thanks!
There is a wrapper called seaborn that sits on top of matplotlib that does nice job of displaying the colormap or selected colors. For example:
sns.palplot(sns.color_palette("coolwarm", 7))
I suggest this over standard matplotlib since it exposes more support for working with color schemes and conversions as mentioned in the other part of your question. If you don't want to use an outside library, just modify the source code that plots this:
def palplot(pal, size=1):
"""Plot the values in a color palette as a horizontal array.
Parameters
----------
pal : sequence of matplotlib colors
colors, i.e. as returned by seaborn.color_palette()
size :
scaling factor for size of plot
"""
n = len(pal)
f, ax = plt.subplots(1, 1, figsize=(n * size, size))
ax.imshow(np.arange(n).reshape(1, n),
cmap=mpl.colors.ListedColormap(list(pal)),
interpolation="nearest", aspect="auto")
ax.set_xticks(np.arange(n) - .5)
ax.set_yticks([-.5, .5])
ax.set_xticklabels([])
ax.set_yticklabels([])

Categories