Plotly Polar Plot with Color as Hover Info - plotly-python

I am trying to visulalize a heat distribution across a radial object using plotly.
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
r, theta = np.mgrid[0.1:1:20j, 0:360:2j]
# %%
T = np.linspace(130,100,20)
color = np.ones(r.shape) * T[:,np.newaxis]
fig = go.Figure(go.Barpolar(
r=r.ravel(),
theta=theta.ravel(),
marker_color=color.ravel(),
marker={"showscale": True,
"colorscale": px.colors.sequential.RdBu_r,},
opacity=1))
margin = 10
fig.update_layout(
showlegend=True,
polar=dict(
radialaxis_layer="above traces",
angularaxis_direction="clockwise",
angularaxis_color="white",
angularaxis_showgrid=False,
radialaxis_showgrid=False,
radialaxis_showline=False,
radialaxis_tickvals=[], # Radii ticks
bargap=0, # Ensure cells will touch
hole=0.0, # Center gap
),
)
fig.show()
But now the hover_info shows only the info on radius and theta (spatial), but I would like to actually let it show the color-value (temperature, T).
As a goodie on top, if I could get rid of the white concentric lines between the segments would be amazing. I tried *_showgrid=False but it does not work, maybe it's part of the bar shape?

Related

How to rotate axis label of plotly parallel coordinates plot?

How to rotate axis label of plotly parallel coordinates plot?
The following image is what I wan to do:
I attached a source script:
import plotly.express as px
df = px.data.iris()
fig = px.parallel_coordinates(df, color="species_id",
dimensions=['sepal_width', 'sepal_length', 'petal_width',
'petal_length'],
color_continuous_scale=px.colors.diverging.Tealrose,
color_continuous_midpoint=2)
fig.show()

Changing only the line properties inside the circle when using pie in matplotlib

When I am segmenting a circle with pie from matplotlib I would like to change the properties of the lines only inside the circle:
plt.rcParams['patch.edgecolor'] = 'lightgrey'
plt.rcParams['patch.linewidth'] = 1
Affect all the lines including the line of the circle itsef.
Step 1 - changing 'inner' lines
As usual it is a good idea to look at the matplotlib API documentation, where we find that pie plot provides a lot of arguments, one of which is wedgeprops
wedgeprops: [ None | dict of key value pairs ]
Dict of arguments passed to the wedge objects making the pie. For example, you can pass in wedgeprops = { ‘linewidth’ : 3 } to set the width of the wedge border lines equal to 3. For more details, look at the doc/arguments of the wedge object.
One of the arguments to Wedge is edgecolor, another is linewidth.
So in total you have to call
plt.pie([215, 130], colors=['b', 'r'],
wedgeprops = { 'linewidth' : 1 , 'edgecolor' : 'lightgrey'} )
However, since this also changes the outline of the pie diagram we need...
Step 2 - setting circonference circle
Now, in order to get a circle around the pie, or restore the initial linestyle for the circonference of the pie, we can set a new Circle patch with the desired properties on top of the pie.
The complete solution then looks something like this
import matplotlib.pyplot as plt
import matplotlib.patches
fig, ax = plt.subplots(figsize=(3,3))
ax.axis('equal')
slices, labels = ax.pie([186, 130, 85], colors=['b', 'r','y'],
wedgeprops = { 'linewidth' : 1 , 'edgecolor' : 'lightgrey'} )
# get the center and radius of the pie wedges
center = slices[0].center
r = slices[0].r
# create a new circle with the desired properties
circle = matplotlib.patches.Circle(center, r, fill=False, edgecolor="k", linewidth=2)
# add the circle to the axes
ax.add_patch(circle)
plt.show()
For a solution that works also with any pie chart, including exploded pie charts, e.g.
import numpy as np
import matplotlib as plt
data = [1, 2, 3, 1, 4, 2]
explode = [0.05] * len(data)
labels = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'[:len(data)])
fig, ax = plt.subplots()
pie = ax.pie(data, labels=labels, explode=explode)
use one of the following options:
Option A, add lines for each wedge of the pie
pie = ax.pie(data, labels=labels, explode=explode)
for wedge in pie[0]:
ax.plot([wedge.center[0], wedge.r*np.cos(wedge.theta1*np.pi/180)+wedge.center[0]], [wedge.center[1], wedge.r*np.sin(wedge.theta1*np.pi/180)+wedge.center[1]], color='k')
ax.plot([wedge.center[0], wedge.r*np.cos(wedge.theta2*np.pi/180)+wedge.center[0]], [wedge.center[1], wedge.r*np.sin(wedge.theta2*np.pi/180)+wedge.center[1]], color='k')
fig.show()
Option B, add edges to the pie wedges then overwrite the radial edge with another color (e.g. white)
from matplotlib import patches
pie = ax.pie(data, labels=labels, explode=explode, wedgeprops=dict(ec='k')
for wedge in pie[0]:
arc = patches.Arc(wedge.center, 2*wedge.r, 2*wedge.r, 0, theta1=wedge.theta1, theta2=wedge.theta2, ec='w', lw=1.5)
ax.add_patch(arc)
fig.show()

how to overlay a shapefile in matplotlib

In matplotlib how to overlay the shapefile (available in folder) as attached below at the top right position outside the plot.
The code referenced by banderkat:
import matplotlib.pyplot as plt
import Image
import numpy as np
im = Image.open('Jbc4j.jpg')
width = im.size[0]
height = im.size[1]
# We need a float array between 0-1, rather than
# a uint8 array between 0-255
im = np.array(im).astype(np.float) / 255
a = np.random.randint(0,100,100)
b = range(100)
fig = plt.figure(1,figsize=(5, 7), dpi=80, facecolor='w')
ax = fig.add_subplot(111)
ax.scatter(a,b)
fig.canvas.draw()
# With newer (1.0) versions of matplotlib, you can
# use the "zorder" kwarg to make the image overlay
# the plot, rather than hide behind it... (e.g. zorder=10)
fig.figimage(im, fig.bbox.xmax - width, fig.bbox.ymax - height, zorder=0)
# (Saving with the same dpi as the screen default to
# avoid displacing the logo image)
fig.savefig('temp.png', dpi=80)
plt.show()
Produces the following result (imaged cropped to save space).
Changing the zorder=1 will place the image on top.
Other helpful references:
How to change background color for scatter plot in matplotlib
How do you change the size of figures drawn with matplotlib?
Python/Matplotlib - Change the relative size of a subplot
In Matplotlib, what does the argument mean in fig.add_subplot(111)?
Customizing Location of Subplot Using GridSpec
You can use basemap toolkit to load and plot shapefile. Here I've plotted shapeFile in a separate axes and aligned it to top-right of other axes plot using 'subplot2grid'.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import matplotlib.gridspec as gridspec
def plotShapeFile():
# Lambert Conformal Conic map.
m = Basemap(llcrnrlon=-100.,llcrnrlat=0.,urcrnrlon=-20.,urcrnrlat=57.,
projection='lcc',lat_1=20.,lat_2=40.,lon_0=-60.,
resolution ='l',area_thresh=1000.)
# read shapefile.
shp_info = m.readshapefile('C:/basemap-1.0.6/basemap-1.0.6/examples/huralll020','hurrtracks',drawbounds=False)
# find names of storms that reached Cat 4.
names = []
for shapedict in m.hurrtracks_info:
cat = shapedict['CATEGORY']
name = shapedict['NAME']
if cat in ['H4','H5'] and name not in names:
# only use named storms.
if name != 'NOT NAMED': names.append(name)
# plot tracks of those storms.
for shapedict,shape in zip(m.hurrtracks_info,m.hurrtracks):
name = shapedict['NAME']
cat = shapedict['CATEGORY']
if name in names:
xx,yy = zip(*shape)
# show part of track where storm > Cat 4 as thick red.
if cat in ['H4','H5']:
m.plot(xx,yy,linewidth=1.5,color='r')
elif cat in ['H1','H2','H3']:
m.plot(xx,yy,color='k')
# draw coastlines, meridians and parallels.
m.drawcoastlines()
m.drawcountries()
m.drawmapboundary(fill_color='#99ffff')
m.fillcontinents(color='#cc9966',lake_color='#99ffff')
m.drawparallels(np.arange(10,70,20),labels=[1,1,0,0])
m.drawmeridians(np.arange(-100,0,20),labels=[0,0,0,1])
if __name__ == '__main__':
fig=plt.figure()
plt.subplots_adjust(wspace=0.001, hspace=0.001)
ax1=plt.subplot2grid((5,5), (0,0), colspan=4, rowspan=4)
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15,30,45, 10]
explode=(0, 0.05, 0, 0)
p1,t1,at1 = plt.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
plt.title('Raining Hogs and Dogs', bbox={'facecolor':'0.8', 'pad':5})
ax2=plt.subplot2grid((5,5), (0,4), colspan=1, rowspan=1)
#draw shapeFile on the current active axes, i.e. ax2
plotShapeFile()
plt.tight_layout()
plt.show()
Below are links to references I've used:
http://sourceforge.net/projects/matplotlib/files/matplotlib-toolkits/basemap-1.0.6/
http://matplotlib.org/basemap/users/examples.html
Output:

hatched rectangle patches without edges in matplotlib

When trying to add a rectangle patch with a hatch pattern to a plot it seems that it is impossible to set the keyword argument edgecolor to 'none' when also specifying a hatch value.
In other words I am trying to add a hatched rectangle WITHOUT an edge but WITH a pattern filling. This doesnt seem to work. The pattern only shows up if I also allow an edge to be drawn around the rectangle patch.
Any help on how to achieve the desired behaviour?
You should use the linewidth argument, which has to be set to zero.
Example (based on your other question's answer):
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111)
# generate some data:
x,y = np.meshgrid(np.linspace(0,1),np.linspace(0,1))
z = np.ma.masked_array(x**2-y**2,mask=y>-x+1)
# plot your masked array
ax.contourf(z)
# plot a patch
p = patches.Rectangle((20,20), 20, 20, linewidth=0, fill=None, hatch='///')
ax.add_patch(p)
plt.show()
You'll get this image:

Matplotlib histogram with errorbars

I have created a histogram with matplotlib using the pyplot.hist() function. I would like to add a Poison error square root of bin height (sqrt(binheight)) to the bars. How can I do this?
The return tuple of .hist() includes return[2] -> a list of 1 Patch objects. I could only find out that it is possible to add errors to bars created via pyplot.bar().
Indeed you need to use bar. You can use to output of hist and plot it as a bar:
import numpy as np
import pylab as plt
data = np.array(np.random.rand(1000))
y,binEdges = np.histogram(data,bins=10)
bincenters = 0.5*(binEdges[1:]+binEdges[:-1])
menStd = np.sqrt(y)
width = 0.05
plt.bar(bincenters, y, width=width, color='r', yerr=menStd)
plt.show()
Alternative Solution
You can also use a combination of pyplot.errorbar() and drawstyle keyword argument. The code below creates a plot of the histogram using a stepped line plot. There is a marker in the center of each bin and each bin has the requisite Poisson errorbar.
import numpy
import pyplot
x = numpy.random.rand(1000)
y, bin_edges = numpy.histogram(x, bins=10)
bin_centers = 0.5*(bin_edges[1:] + bin_edges[:-1])
pyplot.errorbar(
bin_centers,
y,
yerr = y**0.5,
marker = '.',
drawstyle = 'steps-mid-'
)
pyplot.show()
My personal opinion
When plotting the results of multiple histograms on the the same figure, line plots are easier to distinguish. In addition, they look nicer when plotting with a yscale='log'.