I have map with locations in that area. I want to add 1/6 circle starting from each point in a specific direction so I decided to use polar plot with only one bar.
My locations is of the type(lat,lon) but the code accept location with only one parameter
I saw the same code all over the internet but still after reading the documantation its not working.
import numpy as np
import matplotlib.pyplot as plt
#I removed this line
plt.axes([0,0,1,1])
N = 20
theta = np.arange(0.0, 2*np.pi, 2*np.pi/N)
radii = 10*np.random.rand(N)
width = np.pi/4*np.random.rand(N)
bars = plt.bar(theta, radii, width=width, bottom=0.0)
for r,bar in zip(radii, bars):
bar.set_facecolor( cm.jet(r/10.))
bar.set_alpha(0.5)
plt.show()
right now, when runing it, I don't see a thing eventhough ax belong to my graph
Related
I'm trying to draw a couple of vectors with pyplot.
My approach is to define first the plot size (or axis values), as this will change depending on the job run.
pretty much what i need to do is to draw a straight, upwards-facing vector.
So for the test i am using the same values for x-axis, and two different ones for Y (as that would give me an vertical vector)
problem I face is - whatever i am doing, i can't seem to make the vector straight. It always gets rotated.
Does anyone know what reason there might be for it ?
my current code
import matplotlib.pyplot as plt
import math
start = (162305,299400,162890,299400) #define coordinates for vector
#define plot axis values
top = 163440
bottom = 161910
left = 299595
right = 300510
fig, ax = plt.subplots()
ax.quiver(start[0],start[1],start[2],start[3])
plt.xlim(left,right)
plt.ylim(bottom,top)
plt.autoscale()
plt.show()
and the resulting plot
Hope this would help!
import matplotlib.pyplot as plt
import math
start = (162305,299400,162890,299400) #define coordinates for vector
#define plot axis values
top = 163440
bottom = 161910
left = 299595
right = 300510
fig, ax = plt.subplots()
ax.quiver(start[0],start[1],1,0)
#ax.quiver(x_pos, y_pos, x_dir, y_dir, color)
#give the x_pos, y_pos value
#x_dir=1, y_dir=1, meaning 45 degree angle
#x_dir=1, y_dir=0, meaning 0 degree angle
#x_dir=0, y_dir=1, meaning 90 degree angle
# you put x_dir=start[2] and y_dir=start[3], making an arbitary angle of atan
#(y_dir/x_dir) which makes the angled arrow
plt.xlim(left,right)
plt.ylim(bottom,top)
plt.autoscale()
plt.show()
I'm trying to plot projections of coordinates onto a line, but for some reason, Matplotlib is plotting the projections in a slightly slanted manner. Ideally, I would like the (blue) projections to be perpendicular to the (green) line. Here's an image of how it looks with sample data:
As you can see, the angles between the blue lines and the green line are slightly obtuse instead of right. I tried playing around with the rotation parameter to the annotate function, but this did not help. The code for this plot is below, although the data might look a bit different since the random generator is not seeded:
import numpy as np
import matplotlib.pyplot as plt
prefs = {'color':'purple','edgecolors':'black'}
X = np.dot(np.random.rand(2,2), np.random.rand(2,50)).T
pts = np.linspace(-1,1)
v1_m = 0.8076549717643662
plt.scatter(X[:,0],X[:,1],**prefs)
plt.plot(pts, [v1_m*x for x in pts], color='lightgreen')
for x,y in X:
# slope of connecting line
# y = mx+b
m = -np.reciprocal(v1_m)
b = y-m*x
# find intersecting point
zx = b/(v1_m-m)
zy = v1_m*zx
# draw line
plt.annotate('',(zx,zy),(x,y),arrowprops=dict(linewidth=2,arrowstyle='-',color='lightblue'))
plt.show()
The problem lies in the unequal axes which makes it look like they are not at a right angle. Use plt.axis('equal') to have equal axis spans on x- and y-axis and a square figure with equal height and width. plt.axis('scaled') works the same way. As pointed out by #CedricZoppolo, you should set the equal aspect ratios before plt.show(). As per docs, setting the aspect ratio to "equal" means
same scaling from data to plot units for x and y
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,8))
# Your code here
plt.axis('equal')
plt.show()
Choosing a square figure is not necessary as it works also with rectangular figures as
fig = plt.figure(figsize=(8,6))
# Your code here
plt.axis('equal')
plt.show()
The blue lines not being perpendicular is due to axis not being equal.
You just need to add below line before plt.show()
plt.gca().set_aspect('equal')
Below you can see the resulted graph:
I am trying to reproduce a plot like this:
So the requirements are actually that the grid (that is to be present just on the left side) behaves just like a grid, that is, if we zoom in and out, it is always there present and not dependent on specific x-y limits for the actual data.
Unfortunately there is no diagonal version of axhline/axvline (open issue here) so I was thinking about using the grid from polar plots.
So for that I have two problems:
This answer shows how to overlay a polar axis on top of a rectangular one, but it does not match the origins and x-y values. How can I do that?
I also tried the suggestion from this answer for having polar plots using ax.set_thetamin/max but I get an AttributeError: 'AxesSubplot' object has no attribute 'set_thetamin' How can I use these functions?
This is the code I used to try to add a polar grid to an already existing rectangular plot on ax axis:
ax_polar = fig.add_axes(ax, polar=True, frameon=False)
ax_polar.set_thetamin(90)
ax_polar.set_thetamax(270)
ax_polar.grid(True)
I was hoping I could get some help from you guys. Thanks!
The mpl_toolkits.axisartist has the option to plot a plot similar to the desired one. The following is a slightly modified version of the example from the mpl_toolkits.axisartist tutorial:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
from mpl_toolkits.axisartist import SubplotHost, ParasiteAxesAuxTrans
from mpl_toolkits.axisartist.grid_helper_curvelinear import GridHelperCurveLinear
import mpl_toolkits.axisartist.angle_helper as angle_helper
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
# PolarAxes.PolarTransform takes radian. However, we want our coordinate
# system in degree
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()
# polar projection, which involves cycle, and also has limits in
# its coordinates, needs a special method to find the extremes
# (min, max of the coordinate within the view).
# 20, 20 : number of sampling points along x, y direction
extreme_finder = angle_helper.ExtremeFinderCycle(20, 20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0, np.inf),)
grid_locator1 = angle_helper.LocatorDMS(36)
tick_formatter1 = angle_helper.FormatterDMS()
grid_helper = GridHelperCurveLinear(tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
tick_formatter1=tick_formatter1
)
fig = plt.figure(1, figsize=(7, 4))
fig.clf()
ax = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper)
# make ticklabels of right invisible, and top axis visible.
ax.axis["right"].major_ticklabels.set_visible(False)
ax.axis["right"].major_ticks.set_visible(False)
ax.axis["top"].major_ticklabels.set_visible(True)
# let left axis shows ticklabels for 1st coordinate (angle)
ax.axis["left"].get_helper().nth_coord_ticks = 0
# let bottom axis shows ticklabels for 2nd coordinate (radius)
ax.axis["bottom"].get_helper().nth_coord_ticks = 1
fig.add_subplot(ax)
## A parasite axes with given transform
## This is the axes to plot the data to.
ax2 = ParasiteAxesAuxTrans(ax, tr)
## note that ax2.transData == tr + ax1.transData
## Anything you draw in ax2 will match the ticks and grids of ax1.
ax.parasites.append(ax2)
intp = cbook.simple_linear_interpolation
ax2.plot(intp(np.array([150, 230]), 50),
intp(np.array([9., 3]), 50),
linewidth=2.0)
ax.set_aspect(1.)
ax.set_xlim(-12, 1)
ax.set_ylim(-5, 5)
ax.grid(True, zorder=0)
wp = plt.Rectangle((0,-5),width=1,height=10, facecolor="w", edgecolor="none")
ax.add_patch(wp)
ax.axvline(0, color="grey", lw=1)
plt.show()
I have this polar scatter plot and I would like to show that distances from the origin are measured in centimeters by labelling the scale with a "cm." Any advice on how to do this?
import numpy as np
import matplotlib.pyplot as plt
r = R
theta = o
colors = theta
ax = plt.subplot(111, projection='polar')
c = plt.scatter(theta, r, cmap=plt.cm.hsv)
c.set_alpha(0.75)
plt.show()
Simply adding a label by use of plt.set_ylabel does not seem to work, sadly, as it always gets positioned at the origin. There is a simple way around it, though. You can introduce text with ax.text at an arbitrary position. My suggestion would be, to move the tick labels away from the data to make sure that the label won't be misunderstood and then to introduce the label as follows:
import numpy as np
import matplotlib.pyplot as plt
ax = plt.subplot(111, projection="polar")
ax.set_rlabel_position(270) # Moves the tick-labels
ax.text(0.52, 0.25, "cm", transform=ax.transAxes) # Adds text
plt.show()
The result looks like this:
I did something similar, that should work:
plt.yticks(np.arange(0,np.amax(r),3),["%.1f cm" % x for x in np.arange(0,np.amax(r),3)])
in np.arange(0,np.amax(r),3) the 0 is just minimum tick you want in the graph, the 3 is step you want ticks should be.
i'm having trouble creating a custom geostationary projection with Basemap. what i'd need is not a full globe projection, but the upper third of a full disc (full width, one third from the top down ). i found an example here:
http://matplotlib.org/basemap/users/geos.html
explaining how to make a projection for the upper right quadrant of the disc using the llcrnrx, llcrnry, urcrnrx, and urcrnry keywords. following the example, i thought i would get my result like this:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
lon_0 = 9.5
fig = plt.figure()
m1 = Basemap(projection='geos',lon_0=lon_0,resolution=None)
m = Basemap(projection='geos',lon_0=lon_0,resolution='l',
# lower left
llcrnrx=0., llcrnry=0.,
# calculate the upper right coordinates, full width
# two 3rds of the height
urcrnrx=m1.urcrnrx, urcrnry=m1.urcrnry-m1.urcrnry/3.)
m.drawcoastlines()
plt.show()
which gives me a weird plot. from the example i though that for the new projection the lower left corner is always (0,0), then you just calculate the width and height coordinates (upper right). this obviously is not the case. with just bare experimentation i have this now:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
lon_0 = 9.5
fig = plt.figure()
m1 = Basemap(projection='geos',lon_0=lon_0,resolution=None)
m = Basemap(projection='geos',lon_0=lon_0,resolution='l',
llcrnrx=-m1.urcrnrx/2., llcrnry=m1.urcrnry/4.,
urcrnrx=m1.urcrnrx/2., urcrnry=m1.urcrnry/2.)
m.drawcoastlines()
plt.show()
which gives me a rough estimate on what i'm after, but i have no idea why this works and what the corner points really represent.
i hope you guys get the drift...