matplotlib imshow how to plot points instead of image? - python

Here is the code:
plots=imshow(Z,extent=extent,origin,cmap=cmap,aspect='auto',vmin=vmin,vmax=vmax)
plots.plot(Response,component,vrange)
It plots an image based on data list Z, how can I let it print data points instead of an image?
Looks like needs to change to scatter(x, y,...) to plot data points, how difficult it is to change array Z to x, y?

As #jdj081 said, you want to produce a scatter plot.
import os.path
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
# get an image from the sample data directory
fname = os.path.join(matplotlib.get_data_path(), 'sample_data', 'lena.png')
im = plt.imread(fname)
# Reduce the data by a factor of 4 (so that we can see the points)
im = im[::4, ::4]
# generate coordinates for the image. Note that the image is "top down", so the y coordinate goes from high to low.
ys, xs = np.mgrid[im.shape[0]:0:-1, 0:im.shape[1]]
# Scatter plots take 1d arrays of xs and ys, and the colour takes a 2d array,
# with the second dimension being RGB
plt.scatter(xs.flatten(), ys.flatten(), s=4,
c=im.flatten().reshape(-1, 3), edgecolor='face')
plt.show()

You didn't provide much information to go on, but it sounds like you really want to create a scatter plot.
There are many options here depending on what you are plotting and what you want to see, but I have found the following helpful:
Fixing color in scatter plots in matplotlib

import pylab
pylab.figure(1)
pylab.plot([1,2,3,4],[1,7,3,5]) # draw on figure one
pylab.show() # show figure on screen

Related

How can i change the look of my surface plot? I want it to look like a grid an not like a solid surface

I'm trying to generate a 3d plot from a few datapoints. My goal is it, to compare two different datasets and show how good they match at different points. Right now I'm working on the first surface and my supervisor is unhappy with the visualization.
I use the following code at the moment:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import axes3d
# Create the figure and axes objects
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Define the data for the first surface
x1 = [25,35,40,45,50,55,60]
y1 = [1300,4000,5000,5400]
z1 = [8.06,5.81,5.10,4.55,4.1,3.01,2.51,6.46,4.93,4.4,4.03,3.15,2.83,2.4,5.95,4.6,3.87,3.19,2.91,2.7,2.36,5.69,4.29,3.63,3.1,2.85,2.65,2.33]
# Convert the z1 data to 2D arrays
x, y = np.meshgrid(x1, y1)
z1 = np.array(z1).reshape(x.shape)
# Plot the first surface
ax.plot_surface(x, y, z1)
# Show the plot
plt.show()
And as a result the following plot is displayed:
enter image description here
My supervisor wants it to look something like this:
enter image description here
Note that this is a completly different diagram with a different dataset and also different axes.
I wonder if it is even possible to generate such a high resolution of a grid with so few datapoints.
Has is something to do with the way the points are connected in the diagram? In my diagram it looks like a linear interpolation. Is it possible to influence the interpolation?
I would be glad if anyone has an idea and is able to help me.
Thanks, and all the best!

Plot x,y,data in a heatmap with matplotlib

I'm having some trouble to plot data in a 2D heatmap using matplotlib.
The code is the following:
from ugtm import eGTM
import numpy as np
from sklearn import preprocessing
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
X_train = np.random.randn(100, 50)
X_test = np.random.randn(50, 50)
gtm = eGTM().fit(X_train)
responsibilities = gtm.optimizedModel.matR
nodes_cumulated_responsibilities = preprocessing.MinMaxScaler().fit_transform(np.sum(gtm.optimizedModel.matR,0).reshape(-1,1))
nodes_coordinates = gtm.optimizedModel.matX
transformed = eGTM().fit(X_train).transform(X_test)
Z, xedges, yedges = np.histogram2d(nodes_coordinates[:,0], nodes_coordinates[:,1],normed=True,
bins=15,weights=nodes_cumulated_responsibilities[:,0])
plt.figure()
plt.pcolormesh(xedges, yedges,Z.T,cmap='bone_r')
plt.scatter(transformed[:,0],transformed[:,1],color='r')
plt.title('np.hist2d')
I have the "nodes_coordinates" array shape(256,2) which represents the coordinates x,y of the nodes. Then i have "nodes_cumulated_responsibilities" array shape(256,1) representing the value of each node in the respective x,y coordinate. I also have a "transformed" array shape(50,2) representing 50 cells that "X_test" hitted in the heatmap by the eGTM.
Resuming, i would like to make a heatmap using nodes_coordinates and nodes_cumulated_responsibilities as background, and then plot in this map a scatter plot of the "X_test" hitted nodes on the heatmap.
But i want the scatter plot to be in the center of the node for any X_train or any X_test.. This is whats i don't know how to do.
Some points for this code:
The size of the map is 16x16 by default for any size of X_test, but it can be set to any integer, thus the map can be any nxn.
The plt.pcolormesh needs the np.histogram2d to get a meshgrid with edges added to it. But i don't like to use np.histogram2d since i need to pass the 'bins' argument to adjust the heatmap correctly and i suspected it could lead me to some wrong maps or scatters.
The np.meshgrid gives me a meshgrid for the heatmap but without the edges, so i cant use this with pcolormesh.
The approach to use the plt.imshow to plot the heatmap using the np.meshgrid seems more trustable. But i don't know how to convert the 1D array "nodes_cumulated_responsibilities" to a 256x256 array.
A very similiar example of what i want to do is in: https://github.com/JustGlowing/minisom/blob/master/examples/BasicUsage.ipynb
Example of heatmap with scatter plot

how to plot new data on an image?

I have a calculated data (x,y) which I would like to put on top of an image from a paper to compare with some of its boundaries. If this image was a 2D x,y plot, I would have extracted easily the points and then plot together with mine. However this image is a 3D color plot, therefore if I want just to read the image, define my coordinates according to it and plot my data on top, so at the end would seem like 2 layers.
I can plot scatter points by following:
import matplotlib.pyplot as plt
im = plt.imread('fig_exp.png')
implot = plt.imshow(im)
# put a blue dot at (10, 20)
plt.scatter([10], [20], c='r', s=2000, marker=u'*')
plt.show()
But how can I define image coordinates so I can plot e.g
x=[-100,-80,-60,-40]
y=[10,15,20,25]
plt.plot(x,y,'-ro')
The problem here is that I dont know how to define the coordinates as in the figure. Beside I dont know how to plot not as scatter but a line.
I appreciate any helpful solution!
You are looking for the extent= keyword argument to imshow() as detailed in the documentation
As for your second question, if you want a line plot, you use the plot() function instead of scatter().

2D color plot with irregularly spaced samples (matplotlib.mlab.griddata)

cI previously posted this over at code review, but moved it over here as I was told it is more fitting.
Basically, I want to create a colorplot of some irregularly sampled data. I've had some success with the interpolation using matplotlib.mlab.griddata. When I plot the interpolated data (using matplotlib.pyplot.imshow) however, the edges of the domain appear to be left blank. This gets better if I increase the grid density (increase N in the code) but doesn't solve the problem.
I've attached my code and would like to upload an image of the plot I can generate, but am still lacking the reputation to post an image ;)
edit: That has changed now, uploaded the plot after the changes proposed by Ajean:
. Can someone help me out as to what is going wrong?
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.mlab import griddata
# Generate Data
X=np.random.random(100)
Y=2*np.random.random(100)-1
Z=X*Y
# Interpolation
N=100j
extent=(0,1,-1,1)
xs,ys = np.mgrid[extent[0]:extent[1]:N, extent[2]:extent[3]:N]
resampled=griddata(X,Y,Z,xs,ys,interp='nn')
#Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlabel('X')
ax.set_ylabel('Y')
cplot=ax.imshow(resampled.T,extent=extent)
ticks=np.linspace(-1,1,11)
cbar=fig.colorbar(magplot,ticks=ticks,orientation='vertical')
cbar.set_label('Value', labelpad=20,rotation=270,size=16)
ax.scatter(X,Y,c='r')
It is because your calls to random don't provide you with any values at the boundary corners, therefore there is nothing to interpolate with. If you change X and Y definitions to
# Just include the four corners
X=np.concatenate([np.random.random(100),[0,0,1,1]])
Y=np.concatenate([2*np.random.random(100)-1,[-1,1,1,-1]])
You'll fill in the whole thing.

Matplotlib : quiver and imshow superimposed, how can I set two colorbars?

I have a figure that consists of an image displayed by imshow(), a contour and a vector field set by quiver(). I have colored the vector field based on another scalar quantity. On the right of my figure, I have made a colorbar(). This colorbar() represents the values displayed by imshow() (which can be positive and negative in my case). I'd like to know how I could setup another colorbar which would be based on the values of the scalar quantity upon which the color of the vectors is based. Does anyone know how to do that?
Here is an example of the image I've been able to make. Notice that the colors of the vectors go from blue to red. According to the current colorbar, blue means negative. However I know that the quantity represented by the color of the vector is always positive.
Simply call colorbar twice, right after each plotting call. Pylab will create a new colorbar matching to the latest plot. Note that, as in your example, the quiver values range from 0,1 while the imshow takes negative values. For clarity (not shown in this example), I would use different colormaps to distinguish the two types of plots.
import numpy as np
import pylab as plt
# Create some sample data
dx = np.linspace(0,1,20)
X,Y = np.meshgrid(dx,dx)
Z = X**2 - Y
Z2 = X
plt.imshow(Z)
plt.colorbar()
plt.quiver(X,Y,Z2,width=.01,linewidth=1)
plt.colorbar()
plt.show()
Running quiver doesn't necessarily return the type of mappable object that colorbar() requires. I think it might be because I explicitly "have colored the vector field based on another scalar quantity" like Heimdall says they did. Therefore, Hooked's answer didn't work for me.
I had to create my own mappable for the color bar to read. I did this by using Normalize from matplotlib.colors on the data that I wanted to use to color my quiver vectors (which I'll call C, which is an array of the same shape as X, Y, U, and V.)
My quiver call looks like this:
import matplotlib.pyplot as pl
import matplotlib.cm as cm
import matplotlib.colors as mcolors
import matplotlib.colorbar as mcolorbar
pl.figure()
nz = mcolors.Normalize()
nz.autoscale(C)
pl.quiver(X, Y, U, V, color=cm.jet(nz(C)))
cax,_ = mcolorbar.make_axes(pl.gca())
cb = mcolorbar.ColorbarBase(cax, cmap=cm.jet, norm=nz)
cb.set_label('color data meaning')
Giving any other arguments to the colorbar function gave me a variety of errors.

Categories

Resources