I have the data of azimuth and the magnitude of the earth property and would like to plot it on the polar azimuthal histrogram (like a rose diagram)
This is the excerpt of the data:
degrees velocity
22.44903 9449.275
22.4512 9474.46
22.45321 9717.624
22.45537 9745.26
22.45739 9746.532
22.45953 9372.272
22.46157 9899.907
22.46369 9499.646
22.46581 9856.678
22.46786 9811.213
22.46999 9765.846
22.47202 9814.11
22.47418 9974.829
22.47619 10162.89
This is what I have tried, but it produces the plot that is not similar to the one I have expected:
from physt import histogram, binnings, special
import numpy as np
import matplotlib.pyplot as plt
data = genfromtxt(file, delimiter=',')
x=data[:,0]
y=data[:,1]
hist = special.polar_histogram(x, y)
ax = hist.plot.polar_map()
I suspect there could be a problem with conversion of coordinates. What I want is simply distribution (histogram) of values plotted along the azimuth axis
Try with seaborn pakage
import seaborn as sns
sns.barplot(x,y)
Related
I am processing x, y, and z data to have a floor map with high and lows. Z being a displacement sensor. I need to plot a topographical map with gradients. I currently have a 3D scatter plot and a contour plot using matplotlib widgets. Those work great, but a wireframe map or topgraphical map would work best. Either 2D or 3D work as well. Thank you in advance!
Current outputs:
3D Scatter
3D Contour
Example of what I am trying to achieve:
Bokeh surface 3D plot
2D plot
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import holoviews as hv
from bokeh.models import ColumnDataSource
from mpl_toolkits.mplot3d import Axes3D
from holoviews import opts
hv.extension('bokeh', 'matplotlib')
%matplotlib widget
%matplotlib inline
%matplotlib nbagg
%matplotlib ipympl
plt.style.use('seaborn-white')
#Extend width of Jupyter Notebook
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))
#Read CSV
df = pd.read_csv('Floor Scan.csv')
clean_df = df.dropna(axis = 0, how ='any')
print(clean_df)
print('')
z_offset = (clean_df['Displacement (in)'].min())
z_offset_abs = abs(z_offset)
print("Minimum Z:" + str(z_offset))
#3D SCATTER
fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111, projection='3d')
x = clean_df['fActualPosition_X (-)']
y = clean_df['fActualPosition_Y (-)']
z = clean_df['Displacement (in)']
ax.scatter(x, y, (z + z_offset_abs), c='b', marker='^')
plt.xlabel("fActualPosition_X (-)")
plt.ylabel("fActualPosition_Y (-)")
plt.show()
plt.savefig('Floor_Map_Scatter_3D.svg')
#3D CONTOUR
fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111, projection='3d')
X = clean_df['fActualPosition_X (-)'].astype(np.uint8)
Y = clean_df['fActualPosition_Y (-)'].astype(np.uint8)
Z = clean_df['Displacement (in)'].astype(np.uint8)
flatX = np.asarray(clean_df['fActualPosition_X (-)'])
flatY = np.asarray(clean_df['fActualPosition_Y (-)'])
flatZ = np.asarray(clean_df['Displacement (in)'])
# flatX, flatY = np.meshgrid(X, Y)
# flatZ = function(flatX, flatY, Z)
# print(flatX)
# print('')
# print(flatY)
# print('')
# print(flatZ)
# print('')
plt.tricontourf(flatX, flatY, (flatZ+z_offset_abs),20)
plt.show();
plt.savefig('Floor_Map_Contour_3D.svg')
It sounds like your original data is in the form of isolated points (from a range-measuring device like LIDAR?), and what you want is not simply to plot those points, but first to infer or interpolate a surface from those points and then plot that surface. The two desired examples both take an already calculated grid of values and plot them either as a surface or as an image, so first you need to make such a grid, which is not strictly a plotting problem but one of data processing.
One typical way of creating the grid is to aggregate the values into Cartesian coordinates, basically just counting the average value of the scatter points per grid cell. Another is to connect up all the points into a triangular mesh, which may or may not actually form a surface (a function mapping from x,y -> z).
You can use our library Datashader to aggregate just about any set of data into a regular grid, and can then display it as images or contours using hvPlot (https://hvplot.holoviz.org/user_guide/Gridded_Data.html) or as a surface or wireframe using HoloViews (http://holoviews.org/reference/elements/plotly/Surface.html#elements-plotly-gallery-surface).
If you want an unstructured grid, you can use scipy.spatial to compute a triangulation, then HoloViews to visualize it (http://holoviews.org/reference/elements/bokeh/TriMesh.html#elements-bokeh-gallery-trimesh).
How do you go about plotting data over a background image in Python?
For example if I had some gridded pressure data of shape [180,360] (lat,lon)
I could easily plot data by;
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
m = Basemap(projection='ortho',resolution='c',lat_0=45,lon_0=0)
lat = np.linspace(-90,90,180)
lon = np.linspace(-180,180,360)
lon,lat = np.meshgrid(lon,lat)
X, Y = m(lon, lat)
m.contourf(X,Y,Pressure)
plt.show()
etc etc. But if I add a background , e.g.
m.bluemarble()
I cant plot on top of this layer. I've heard of imshow, but how does that take into account gridded data? Not sure how to plot pressure on top of this. Or possibly the alpha attribute in plotting. Thanks!
For example setting alpha to 0.5 in the plt function, I get some horrible mix of colours (and white lines randomly appear);
I am looking for a plot that is rotated 90 degree in clockwise directions. An similar example of such plot is "hist(x, orientation='horizontal')". Is there any way to achieve similar orientation.
#Make horizontal plots.
import random
import matplotlib.pyplot as plt
x = random.sample(range(1000), 100)
x
plt.plot(x) #orientation='horizontal'
plt.show()
plt.plot(x) plots your x values automatically against the y-axis. In order to get a rotated plot you have to plot your x values against the x axis. So you'll need a to make vector for the y-axis, which has the same length as your sample.
import random
import matplotlib.pyplot as plt
import numpy as np
x=random.sample(1000)
y=np.arange(1000)
plt.plot(x,y)
Using plt.plot(x), matplotlib takes your x-values as its y-values and generates a vector for the x axis automatically.
I have a problem changing my axis labels in Matplotlib. I want to change the radial axis options in my Polar Plot.
Basically, I'm computing the distortion of a cylinder, which is nothing but how much the radius deviates from the original (perfectly circular) cylinder. Some of the distortion values are negative, while some are positive due to tensile and compressive forces. I'm looking for a way to represent this in cylindrical coordinates graphically, so I thought that a polar plot was my best bet. Excel gives me a 'radar chart' option which is flexible enough to let me specify minimum and maximum radial axis values. I want to replicate this on Python using Matplotlib.
My Python script for plotting on polar coordinates is as follows.
#!usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-180.0,190.0,10)
theta = (np.pi/180.0 )*x # in radians
offset = 2.0
R1 = [-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358]
fig1 = plt.figure()
ax1 = fig1.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax1.set_rmax(1)
ax1.plot(theta,R1,lw=2.5)
My plot looks as follows:
But this is not how I want to present it. I want to vary my radial axis, so that I can show the data as a deviation from some reference value, say -2. How do I ask Matplotlib in polar coordinates to change the minimum axis label? I can do this VERY easily in Excel. I choose a minimum radial value of -2, to get the following Excel radar chart:
On Python, I can easily offset my input data by a magnitude of 2. My new dataset is called R2, as shown:
#!usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-180.0,190.0,10)
theta = (np.pi/180.0 )*x # in radians
offset = 2.0
R2 = [1.642,1.517,1.521,1.654,1.879,2.137,2.358,2.483,2.479,2.346,2.121,1.863,\
1.642,1.517,1.521,1.654,1.879,2.137,2.358,2.483,2.479,2.346,2.121,1.863,1.642,\
1.517,1.521,1.654,1.879,2.137,2.358,2.483,2.479,2.346,2.121,1.863,1.642]
fig2 = plt.figure()
ax2 = fig2.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax2.plot(theta,R2,lw=2.5)
ax2.set_rmax(1.5*offset)
plt.show()
The plot is shown below:
Once I get this, I can MANUALLY add axis labels and hard-code it into my script. But this is a really ugly way. Is there any way I can directly get a Matplotlib equivalent of the Excel radar chart and change my axis labels without having to manipulate my input data?
You can just use the normal way of setting axis limits:
#!usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-180.0,190.0,10)
theta = (np.pi/180.0 )*x # in radians
offset = 2.0
R1 = [-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358]
fig1 = plt.figure()
ax1 = fig1.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax1.set_ylim(-2,2)
ax1.set_yticks(np.arange(-2,2,0.5))
ax1.plot(theta,R1,lw=2.5)
effectively I have a large 1D array of heights. As a small example consider:
u=array([0,1,2,1,0,2,4,6,4,2,1])
and a 1D array, the same size as u, of radial values which the heights correspond to, e.g.:
r=array([0,1,2,3,4,5,6,7,8,9,10])
Obviously plotting these with:
pylab.plot(r,u)
gives a nice 2D plot.
How can one sweep this out around 360 degrees, to give a 3D contour/surface plot?
If you can imagine it should look like a series of concentric, circular ridges, like for the wavefunction of an atom.
any help would be much appreciated!
You're better off with something more 3D oriented than matplotlib, in this case...
Here's a quick example using mayavi:
from enthought.mayavi import mlab
import numpy as np
# Generate some random data along a straight line in the x-direction
num = 100
x = np.arange(num)
y, z = np.ones(num), np.ones(num)
s = np.cumsum(np.random.random(num) - 0.5)
# Plot using mayavi's mlab api
fig = mlab.figure()
# First we need to make a line source from our data
line = mlab.pipeline.line_source(x,y,z,s)
# Then we apply the "tube" filter to it, and vary the radius by "s"
tube = mlab.pipeline.tube(line, tube_sides=20, tube_radius=1.0)
tube.filter.vary_radius = 'vary_radius_by_scalar'
# Now we display the tube as a surface
mlab.pipeline.surface(tube)
# And finally visualize the result
mlab.show()
#!/usr/bin/python
from mpl_toolkits.mplot3d import Axes3D
import matplotlib
import numpy as np
from scipy.interpolate import interp1d
from matplotlib import cm
from matplotlib import pyplot as plt
step = 0.04
maxval = 1.0
fig = plt.figure()
ax = Axes3D(fig)
u=np.array([0,1,2,1,0,2,4,6,4,2,1])
r=np.array([0,1,2,3,4,5,6,7,8,9,10])
f=interp1d(r,u)
# walk along the circle
p = np.linspace(0,2*np.pi,50)
R,P = np.meshgrid(r,p)
# transform them to cartesian system
X,Y = R*np.cos(P),R*np.sin(P)
Z=f(R)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet)
ax.set_xticks([])
plt.show()