xarray.plot.contour not printing contour labels - matplotlib

I am trying something like this:
import xarray as xr
import numpy as np
(lon,lat)=np.meshgrid(np.arange(0,6,1),np.arange(0,6,1))
da_data=xr.DataArray(data=np.random.randn(6,6),dims=['y','x'],
coords=dict(LAT=(['y','x'],lat), LON=(['y','x'],lon)) )
da_data.plot.contour(kwargs=dict(inline=True))
I can see the contours but no labels. What am I doing wrong?

xarray.plot uses matplotlib as a backend, and you can replace your last line with the following, using matplotlib's Axis.clabel
fig, ax = plt.subplots()
CS = da_data.plot.contour(kwargs=dict(inline=True), ax=ax)
ax.clabel(CS)
See the matplotlib.contour.ContourLabeler.clabel documentation and the countour label demo for more info.

Related

Scale Y axis of matplotlib plot in jupyter notebook

I want to scale Y axis so that I can see values, as code below plots cant see anything other than a thin black line. Changing plot height doesn't expand the plot.
import numpy as np
import matplotlib.pyplot as plt
data=np.random.random((4,10000))
plt.rcParams["figure.figsize"] = (20,100)
#or swap line above with one below, still no change in plot height
#fig=plt.figure(figsize=(20, 100))
plt.matshow(data)
plt.show()
One way to do this is just repeat the values then plot result, but I would have thought it possible to just scale the height of the plot?
data_repeated = np.repeat(data, repeats=1000, axis=0)
You can do it like this:
import numpy as np
import matplotlib.pyplot as plt
data=np.random.random((4, 10000))
plt.figure(figsize=(40, 10))
plt.matshow(data, fignum=1, aspect='auto')
plt.show()
Output:

Is there a way to draw shapes on a python pandas plot

I am creating shot plots for NHL games and I have succeeded in making the plot, but I would like to draw the lines that you see on a hockey rink on it. I basically just want to draw two circles and two lines on the plot like this.
Let me know if this is possible/how I could do it
Pandas plot is in fact matplotlib plot, you can assign it to variable and modify it according to your needs ( add horizontal and vertical lines or shapes, text, etc)
# plot your data, but instead diplaying it assing Figure and Axis to variables
fig, ax = df.plot()
ax.vlines(x, ymin, ymax, colors='k', linestyles='solid') # adjust to your needs
plt.show()
working code sample
import pandas as pd
import matplotlib.pyplot as plt
import seaborn
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
df = seaborn.load_dataset('tips')
ax = df.plot.scatter(x='total_bill', y='tip')
ax.vlines(x=40, ymin=0, ymax=20, colors='red')
patches = [Circle((50,10), radius=3)]
collection = PatchCollection(patches, alpha=0.4)
ax.add_collection(collection)
plt.show()

Creating a grouped bar plot with Seaborn

I am trying to create a grouped bar graph using Seaborn but I am getting a bit lost in the weeds. I actually have it working but it does not feel like an elegant solution. Seaborn only seems to support clustered bar graphs when there is a binary option such as Male/Female. (https://seaborn.pydata.org/examples/grouped_barplot.html)
It does not feel right having to fall back onto matplotlib so much - using the subplots feels a bit dirty :). Is there a way of handling this completely in Seaborn?
Thanks,
Andrew
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import rcParams
sns.set_theme(style="whitegrid")
rcParams.update({'figure.autolayout': True})
dataframe = pd.read_csv("https://raw.githubusercontent.com/mooperd/uk-towns/master/uk-towns-sample.csv")
dataframe = dataframe.groupby(['nuts_region']).agg({'elevation': ['mean', 'max', 'min'],
'nuts_region': 'size'}).reset_index()
dataframe.columns = list(map('_'.join, dataframe.columns.values))
# We need to melt our dataframe down into a long format.
tidy = dataframe.melt(id_vars='nuts_region_').rename(columns=str.title)
# Create a subplot. A Subplot makes it convenient to create common layouts of subplots.
# https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.subplots.html
fig, ax1 = plt.subplots(figsize=(6, 6))
# https://stackoverflow.com/questions/40877135/plotting-two-columns-of-dataframe-in-seaborn
g = sns.barplot(x='Nuts_Region_', y='Value', hue='Variable', data=tidy, ax=ax1)
plt.tight_layout()
plt.xticks(rotation=45, ha="right")
plt.show()
I'm not sure why you need seaborn. Your data is wide format, so pandas does it pretty well without the need for melting:
from matplotlib import rcParams
sns.set(style="whitegrid")
rcParams.update({'figure.autolayout': True})
fig, ax1 = plt.subplots(figsize=(12,6))
dataframe.plot.bar(x='nuts_region_', ax=ax1)
plt.tight_layout()
plt.xticks(rotation=45, ha="right")
plt.show()
Output:

how to prevent seaborn to skip year in xtick label in Timeseries Plot

I have included the screenshot of the plot. Is there a way to prevent seaborn from skipping the xtick labels in timeseries data.
Most seaborn functions return a matplotlib object, so you can control the number of major ticks displayed via matplotlib. By default, matplotlib will auto-scale, which is why it hides some year labels, you can try to set the MaxNLocator.
Consider the following example:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# load data
df = sns.load_dataset('flights')
df.drop_duplicates('year', inplace=True)
df.year = df.year.astype('str')
# plot
fig, ax = plt.subplots(figsize=(5, 2))
sns.lineplot(x='year', y='passengers', data=df, ax=ax)
ax.xaxis.set_major_locator(plt.MaxNLocator(5))
This gives you:
ax.xaxis.set_major_locator(plt.MaxNLocator(10))
will give you
Agree with answer of #steven, just want to say that methods for xticks like plt.xticks or ax.xaxis.set_ticks seem more natural to me. Full details can be found here.

how to draw axes passing through the origin in a 3D plot using matplotlib

I want to create a 3d plot like the following, such that axes pass through the origin with ticks on them.
PS: I could do that for 2D plots using matplotlib (the following figure). I searched a lot to do the same for 3D plots but I did not find any info.
If you want to restrict yourself to just matplotlib then we can use quiver3d plot as shown below. But the results may not be very visually appealing. You can see here how to add 3D text annotations.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.set_xlim(0,2)
ax.set_ylim(0,2)
ax.set_zlim(0,2)
ax.view_init(elev=20., azim=32)
# Make a 3D quiver plot
x, y, z = np.zeros((3,3))
u, v, w = np.array([[1,1,0],[1,0,1],[0,1,1]])
ax.quiver(x,y,z,u,v,w,arrow_length_ratio=0.1)
plt.show()