Plot sample with different colors in matplotlib - python

I tried the following code to plot a set of samples over a 2D plane.
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
# some code generating x and y
matplotlib.rcParams['axes.unicode_minus'] = False
fig, ax = plt.subplots()
ax.plot(x, y, 'o')
ax.set_title('Using hypen instead of unicode minus')
plt.show()
I would like to provide a list of values (where each values ranges from 0 to k-1), so that each sample is displayed with the corresponding color. How would I need to modify the code above?

Related

Plotting 3D distribution in python

I would like to plot my data in 3D like this figure(The filled circles are shown in gray scale based on the declination; darker colours mean lower declination.The dots in the R.A.-Dec. plane are the projection on the celestial plane)
I plot like this but I am not able to get like the given figure given above
import numpy as np, math
import matplotlib.pyplot as plt
from astropy.table import Table
from mpl_toolkits.mplot3d import Axes3D
data=Table.read('test_data.fits')
min_red=min(data['redshift'])
fig = plt.figure(figsize=(16,14))
ax = Axes3D(fig)
ax = fig.gca(projection='3d')
ax.view_init(10,30)
ax.plot(data['ra'], data['dec'], data['redshift'],'ko',markersize=5,linewidth=2)
m=ax.plot(data['ra'], data['dec'], 'ro', markersize=1, color='r', zdir='z', zs=min_red)
ax.set_xlabel('ra')
ax.set_ylabel('dec')
ax.set_zlabel('redshift')
plt.show()
But I got like this figure(the dots in Ra and Dec are the projection on the celestial plane)
How to plot like the first figure. Kindly do help
I think the easiest would be to use Axes3D.scatter as following :
import numpy as np, math
import matplotlib.pyplot as plt
from astropy.table import Table
from mpl_toolkits.mplot3d import Axes3D
data=Table.read('test_data.fits')
min_red=min(data['redshift'])
fig = plt.figure(figsize=(16,14))
ax = Axes3D(fig)
ax = fig.gca(projection='3d')
ax.view_init(10,30)
y=list(data['dec'])
ax.scatter(data['ra'], data['dec'], data['redshift'],'ko', c=y, cmap = 'Greys')
m=ax.plot(data['ra'], data['dec'], 'ro', markersize=1, color='r', zdir='z', zs=min_red)
ax.set_xlabel('ra')
ax.set_ylabel('dec')
ax.set_zlabel('redshift')
plt.show()
As specified in Axes3D.scatter documentation :
A color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. c can be a 2-D array in which the rows are RGB or RGBA, however, including the case of a single row to specify the same color for all points.
My result with the code above

How to make a legend in a plot?

I am unable to figure out a way to get a legend of my plot. My data is a data frame consisting of 3 columns x, y and z. x and y represent the co-ordinates of a point and z is the label(0,1,2,3) that the point belongs to. Sample data :
I need to plot a scatterplot with a legend containing a colour representing a respective label.
I have plotted the scatterplot but am unable to understand how to put the legend in it.
The code I used till now is(dft is the dataframe) :
import matplotlib.pyplot as plt
%matplotlib inline
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot()
ax.scatter(dft['x'] , dft['y'], c=dft['z'], cmap = 'hsv')
plt.show()
The figure I obtained is :
I need a legend for each color.
You can try this code instead:
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(8,8))
plt.scatter(dft['x'] , dft['y'], c=dft['z'], cmap = 'hsv')
plt.colorbar()

Show legend that matplotlib dynamically created

My df has 4 columns: x, y, z, and grouping. I have created a 3D plot, with the assigned color of each point being decided by what grouping it belongs to in that row. For reference, a "grouping" can be any number from 1 to 6. The code is shown below:
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter3D(df.x, df.y, df.z, c=df.grouping)
plt.show()
I would like to show a legend on the plot that shows which color belongs to which grouping. Previously, I was using Seaborn for a 2D plot and the legend was automatically plotted. How can I add this feature with matplotlib?
If the values to be colormapped are numeric, the solution can be as simple as:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
a = np.random.rand(3,40)
c = np.random.randint(1,7, size=a.shape[1])
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
sc = ax.scatter3D(*a, c=c)
plt.legend(*sc.legend_elements())
plt.show()

Histogram at specific coordinates inside axes

What I want to achieve with Python 3.6 is something like this :
Obviously made in paint and missing some ticks on the xAxis. Is something like this possible? Essentially, can I control exactly where to plot a histogram (and with what orientation)?
I specifically want them to be on the same axes just like the figure above and not on separate axes or subplots.
fig = plt.figure()
ax2Handler = fig.gca()
ax2Handler.scatter(np.array(np.arange(0,len(xData),1)), xData)
ax2Handler.hist(xData,bins=60,orientation='horizontal',normed=True)
This and other approaches (of inverting the axes) gave me no results. xData is loaded from a panda dataframe.
# This also doesn't work as intended
fig = plt.figure()
axHistHandler = fig.gca()
axScatterHandler = fig.gca()
axHistHandler.invert_xaxis()
axHistHandler.hist(xData,orientation='horizontal')
axScatterHandler.scatter(np.array(np.arange(0,len(xData),1)), xData)
A. using two axes
There is simply no reason not to use two different axes. The plot from the question can easily be reproduced with two different axes:
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")
xData = np.random.rand(1000)
fig,(ax,ax2)= plt.subplots(ncols=2, sharey=True)
fig.subplots_adjust(wspace=0)
ax2.scatter(np.linspace(0,1,len(xData)), xData, s=9)
ax.hist(xData,bins=60,orientation='horizontal',normed=True)
ax.invert_xaxis()
ax.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax2.tick_params(axis="y", left=0)
plt.show()
B. using a single axes
Just for the sake of answering the question: In order to plot both in the same axes, one can shift the bars by their length towards the left, effectively giving a mirrored histogram.
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")
xData = np.random.rand(1000)
fig,ax= plt.subplots(ncols=1)
fig.subplots_adjust(wspace=0)
ax.scatter(np.linspace(0,1,len(xData)), xData, s=9)
xlim1 = ax.get_xlim()
_,__,bars = ax.hist(xData,bins=60,orientation='horizontal',normed=True)
for bar in bars:
bar.set_x(-bar.get_width())
xlim2 = ax.get_xlim()
ax.set_xlim(-xlim2[1],xlim1[1])
plt.show()
You might be interested in seaborn jointplots:
# Import and fake data
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
data = np.random.randn(2,1000)
# actual plot
jg = sns.jointplot(data[0], data[1], marginal_kws={"bins":100})
jg.ax_marg_x.set_visible(False) # remove the top axis
plt.subplots_adjust(top=1.15) # fill the empty space
produces this:
See more examples of bivariate distribution representations, available in Seaborn.

Python matplotlib Colorfunction

I would like to use a ColorFunction similar to that in Mathematica for my plots in python.
In other words, I would like to call pyplot.plot(x, y, color=c), where c is a vector, defining the color of each data point.
Is there any way to achieve this using the matplotlib library?
To the best of my knowledge, there is no equivalent in Matplotlib, but we can get the similar result following two steps: draw points with varied colors and draw the line.
Here is a demo.
The source code,
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
import random
fig, ax = plt.subplots()
nrof_points = 100
x = np.linspace(0, 10, nrof_points)
y = np.sin(x)
colors = cm.rainbow(np.linspace(0, 1, nrof_points)) # generate a bunch of colors
# draw points
for idx, point in enumerate(zip(x, y)):
ax.plot(point[0], point[1], 'o', color=colors[idx], markersize=10)
# draw the line
ax.plot(x, y, 'k')
plt.grid()
plt.show()
While I agree with #SparkAndShine that there is no way to parameterize the color of one line, it is possible to color many lines to create a visual effect that is largely the same. This is at the heart of a demo in the MatPlotLib documentation. However, this demo is not the simplest implementation of this principle. Here is an alternate demo based on #SparkAndShine's response:
colored sine (can't post as image since I don't have the reputation)
Source code:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
fig, ax = plt.subplots()
nrof_points = 100
x = np.linspace(0, 10, nrof_points)
y = np.sin(x)
colors = cm.rainbow(np.linspace(0, 1, nrof_points)) # generate a bunch of colors
# draw points
for idx in range(0,np.shape(x)[0]-2,1):
ax.plot(x[idx:idx+1+1], y[idx:idx+1+1], color=colors[idx])
# add a grid and show
plt.grid()
plt.show()

Categories