plotting stations on map - pandas

i have three stations named as A, B, C. I want to plot them on a map using matplotlib basemap.
station A: latitude=17.8 longitude=74.48
station B: latitude=-25.02 longitude=25.60
station C: latitude=44.58 longitude=-123.30
As i am new to python and that to matplotlib, i am confused how should i plot it.
i tried the code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
plt.figure(figsize=(8, 8))
m = Basemap(projection='ortho', resolution=None, lat_0=50, lon_0=-100)
m.bluemarble(scale=0.5);
But it doesnot plot any of my stations.so i hope experts may help me.Thanks in advance.

Here's an example based on your data with which you might play around:
import pygmt
import pandas as pd
# create df with station information
data = {'lon':[74.48, 25.60, -123.30],
'lat':[17.8, -25.02, 44.58],
'station':['A', 'B', 'C']}
df = pd.DataFrame(data)
fig = pygmt.Figure()
pygmt.config(MAP_GRID_PEN = '0.25p,gray')
fig.grdimage("#earth_day_10m", region="g", projection="G130/50/12c", frame="g")
fig.plot(x = df.lon, y = df.lat, style = "t1c", color = "red3", pen = "1p,white")
fig.show()
The tutorials in the User Guide and the gallery examples are a good starting point when working with PyGMT the first time!

Related

How make scatterplot in pandas readable

I've been playing with Titanic dataset and working through some visualisations in Pandas using this tutorial. https://www.kdnuggets.com/2023/02/5-pandas-plotting-functions-might-know.html
I have a visual of scatterplot having used this code.
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('train.csv')
I was confused by bootstrap plot result so went on to scatterplot.
pd.plotting.scatter_matrix(df, figsize=(10,10), )
plt.show()
I can sort of interpret it but I'd like to put the various variables at top and bottom of every column. Is that doable?
You can use:
fig, ax = plt.subplots(4, 3, figsize=(20, 15))
sns.scatterplot(x = 'bedrooms', y = 'price', data = dataset, whis=1.5, ax=ax[0, 0])
sns.scatterplot(x = 'bathrooms', y = 'price', data = dataset, whis=1.5, ax=ax[0, 1])

Barplot per each ax in matplotlib

I have the following dataset, ratings in stars for two fictitious places:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'id':['A','A','A','A','A','A','A','B','B','B','B','B','B'],
'rating':[1,2,4,5,5,5,3,1,3,3,3,5,2]})
Since the rating is a category (is not a continuous data) I convert it to a category:
df['rating_cat'] = pd.Categorical(df['rating'])
What I want is to create a bar plot per each fictitious place ('A or B'), and the count per each rating. This is the intended plot:
I guess using a for per each value in id could work, but I have some trouble to decide the size:
fig, ax = plt.subplots(1,2,figsize=(6,6))
axs = ax.flatten()
cats = df['rating_cat'].cat.categories.tolist()
ids_uniques = df.id.unique()
for i in range(len(ids_uniques)):
ax[i].bar(df[df['id']==ids_uniques[i]], df['rating'].size())
But it returns me an error TypeError: 'int' object is not callable
Perhaps it's something complicated what I am doing, please, could you guide me with this code
The pure matplotlib way:
from math import ceil
# Prepare the data for plotting
df_plot = df.groupby(["id", "rating"]).size()
unique_ids = df_plot.index.get_level_values("id").unique()
# Calculate the grid spec. This will be a n x 2 grid
# to fit one chart by id
ncols = 2
nrows = ceil(len(unique_ids) / ncols)
fig = plt.figure(figsize=(6,6))
for i, id_ in enumerate(unique_ids):
# In a figure grid spanning nrows x ncols, plot into the
# axes at position i + 1
ax = fig.add_subplot(nrows, ncols, i+1)
df_plot.xs(id_).plot(axes=ax, kind="bar")
You can simplify things a lot with Seaborn:
import seaborn as sns
sns.catplot(data=df, x="rating", col="id", col_wrap=2, kind="count")
If you're ok with installing a new library, seaborn has a very helpful countplot. Seaborn uses matplotlib under the hood and makes certain plots easier.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({'id':['A','A','A','A','A','A','A','B','B','B','B','B','B'],
'rating':[1,2,4,5,5,5,3,1,3,3,3,5,2]})
sns.countplot(
data = df,
x = 'rating',
hue = 'id',
)
plt.show()
plt.close()

How do I subplot each contour with a legenda?

I want to subplot correctly and get two legends. I think that if you open the added image you get what I am trying to achieve because it sucks right now. I am learning to code so I don't understand everyone else's code on here so I am probably asking something that has been asked tons but I don't understand anyone else's code. My current code exists of the following
from IPython import get_ipython
get_ipython().magic('reset -f')
# Set up your graphics environment
get_ipython().magic('matplotlib')
# Import the modules you always need
import numpy as np
import matplotlib.pyplot as plt
# Import the modules for 3D plotting
from mpl_toolkits.mplot3d.axes3d import Axes3D
from matplotlib import cm
plt.close('all')
slopeangle = np.arange(5, 45, 1)
intangle = np.arange(20, 45, 1)
slopeangle_m, intangle_m = np.meshgrid(slopeangle, intangle)
#F = np.zeros(np.shape(slopeangle_m)
F = (((15.2-(9.81*0.5))*2.0*((np.cos(slopeangle_m*np.pi/180))**2)*np.tan(((np.pi*intangle_m)/180)))/(15.2*2.0*np.sin(slopeangle_m*np.pi/180)*(np.cos(slopeangle_m*np.pi/180))))
M0 = (((15.2-(9.81*0))*2.0*((np.cos(slopeangle_m*np.pi/180))**2)*np.tan(((np.pi*intangle_m)/180)))/(15.2*2.0*np.sin(slopeangle_m*np.pi/180)*(np.cos(slopeangle_m*np.pi/180))))
M75 = (((15.2-(9.81*0.75))*2.0*((np.cos(slopeangle_m*np.pi/180))**2)*np.tan(((np.pi*intangle_m)/180)))/(15.2*2.0*np.sin(slopeangle_m*np.pi/180)*(np.cos(slopeangle_m*np.pi/180))))
fig2 = plt.figure()
ax = fig2.add_subplot(211)
plt.contourf(slopeangle, intangle, M0, levels=[np.min(M0),1 ,np.max(M0)], cmap=plt.cm.seismic)
ax.legend
ax=plt.gca()
ax.set_title("Factor m as value 0")
ax.set_xlabel('Slope angle (°)')
ax.set_ylabel('Internal angle (°)')
ax2 = fig2.add_subplot(212)
plt.contourf(slopeangle, intangle, M75, levels=[np.min(M75),1 ,np.max(M75)], cmap=plt.cm.seismic)
ax2=plt.gca()
ax2.set_title("Factor m as value 0.75")
ax2.set_xlabel('Slope angle (°)')
ax2.set_ylabel('Internal angle (°)')
I get the following

How to plot frequency distribution graph using Matplotlib?

I trust you are doing well. I am using a data frame in which there are two columns screens and it's frequency. I am trying to find out the relationship between the screen and the frequency of the appearance of the screens. Now I want to know, for all screens what are all of the frequencies as sort of a summary graph. Imagine putting all of those frequencies into an array, and wanting to study the distribution in that array. Below is my code that I have tried so far:
data = pd.read_csv('frequency_list.csv')
new_columns = data.columns.values
new_columns[1] = 'frequency'
data.columns = new_columns
import matplotlib.pyplot as plt
%matplotlib inline
dataset = data.head(10)
dataset.plot(x = "screen", y = "frequency", kind = "bar")
plt.show()
col_one_list = unpickled_df['screen'].tolist()
col_one_arr = unpickled_df['screen'].head(10).to_numpy()
plt.hist(col_one_arr) #gives you a histogram of your array 'a'
plt.show() #finishes out the plot
Below is the screenshot of my data frame containing screen as one column and frequency as another. Can you help me to find out a way to plot a frequency distribution graph? Thanks in advance.
Will a bar plot work? Here's an example:
import pandas as pd
import matplotlib.pyplot as plt
freq = [102,98,56,117]
screen = ['A','B','C','D']
df = pd.DataFrame(list(zip(screen, freq)), columns=['screen', 'freq'])
plt.bar(df.screen,df.freq)
plt.xlabel('x')
plt.ylabel('count')
plt.show()

Add a category without data in it to a plot in seaborn

I am making plotting some data as a catplot like this:
ax = sns.catplot(x='Kind', y='VAF', hue='Sample', jitter=True, data=df, legend=False)
The trouble is that some of the categories of 'VAF' contain no data, and the corresponding label is not added to the plot. Is there a way to retain the label but just not plot any points for it?
Here is a reproducible example to help explain:
x=pd.DataFrame({'Data':[1,3,4,6,3,2],'Number':['One','One','One','One','Three','Three']})
plt.figure()
ax = sns.catplot(x='Number', y='Data', jitter=True, data=x)
In this plot you can see that on the x-axis, samples One and Three are displayed. But imagine that there is also a sample Two that just had no data points in it. How can I display One, Two, and Three on the x-axis?
Order parameter
Of course one would need to know which categories are expected. Given a list of expected categories, one can use the order parameter to supply the expected categories.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.DataFrame({'Data':[1,3,4,6,3,2],
'Number':['One','One','One','One','Three','Three']})
exp_cats = ["One", "Two", "Three"]
ax = sns.stripplot(x='Number', y='Data', jitter=True, data=df, order=exp_cats)
plt.show()
Alternatives
The above works with matplotlib 2.2.3, but not with 3.0. It works again with the current development version (hence 3.1). For the moment, there are the following alternatives:
A. Looping over categories
Given a list of expected categories, one can just loop over them and plot a scatter of each category.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'Data':[1,3,4,6,3,2],
'Number':['One','One','One','One','Three','Three']})
exp_cats = ["One", "Two", "Three"]
for i, cat in enumerate(exp_cats):
cdf = df[df["Number"] == cat]
x = np.zeros(len(cdf))+i+.2*(np.random.rand(len(cdf))-0.5)
plt.scatter(x, cdf["Data"].values)
plt.xticks(range(len(exp_cats)), exp_cats)
plt.show()
B. Map categories to numbers.
You can map the expected categories to numbers and plot numbers instead of categories.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'Data':[1,3,4,6,3,2],
'Number':['One','One','One','One','Three','Three']})
exp_cats = ["One", "Two", "Three"]
df["IntNumber"] = df["Number"].map(dict(zip(exp_cats, range(len(exp_cats)))))
plt.scatter(df["IntNumber"] + .2*(np.random.rand(len(df))-0.5), df["Data"].values,
c = df["IntNumber"].values.astype(int))
plt.xticks(range(len(exp_cats)), exp_cats)
plt.show()
C. Appending missing categories to the dataframe
Finally you may append nan values to the dataframe to make sure each expected category appears in it.
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.DataFrame({'Data':[1,3,4,6,3,2],
'Number':['One','One','One','One','Three','Three']})
exp_cats = ["One", "Two", "Three"]
dfa = df.append(pd.DataFrame({'Data':[np.nan]*len(exp_cats), 'Number':exp_cats}))
ax = sns.stripplot(x='Number', y='Data', jitter=True, data=dfa, order=exp_cats)
plt.show()