Matplotlib style sheet not being applied - python

I've been trying several style sheets but none of them seems to be applied to the canvas. This is the first time I'm using twinx() so maybe that's the issue. The code I have tried is below -
import pickle
import numpy as np
import matplotlib.pyplot as plt
with open("acc.pkl", "rb") as a:
acc = pickle.load(a)
with open("loss.pkl", "rb") as b:
loss = pickle.load(b)
x = np.array([point for point in range(100)])
fig, graph_1 = plt.subplots()
points_1 = np.array(acc)
graph_1.plot(x, points_1, 'b')
graph_2 = graph_1.twinx()
points_2 = np.array(loss)
graph_2.plot(x, points_2, 'r')
plt.style.use('fivethirtyeight')
plt.xlabel('epochs')
fig.tight_layout()
plt.show()

The stylesheet parameters are applied at the time the object that uses them is created.
E.g. if you want to have a figure and axes in a given style, you need to set the style sheet before creating them via plt.subplots.
plt.style.use('fivethirtyeight')
fig, graph_1 = plt.subplots()

Related

Matplotlib: Generating Subplots for Multiple Time Series

I have the following dataset that was randomly generated through a simulation I am building:
https://drive.google.com/drive/folders/1JF5QrliE9s8VPMaGc8Z-mwpFhNWkeYtk?usp=sharing
For debugging purposes, I would like to be able to view this data in a series of small multiples. Like this:
I am attempting to do this using matplotlib and pandas. Here is my code for that:
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
def graph_file(f: str):
"""
Graphs a single file of data
and exports it as a pdf of separate charts.
"""
data = pd.read_csv(f)
header = data.columns
fname = f[:-4] + '.pdf'
with PdfPages(fname) as pdf:
n = len(header)
time: str = header[0]
# Multiple charts on one page
fig = plt.figure()
for i in range(1, n):
y: str = header[i]
ax = fig.add_subplot()
data.plot(x=time, y=y)
pdf.savefig(bbox_inches='tight')
When I open up the .csv file and try to run the function using a Jupyter notebook, I get the same deprecation warning over and over again:
<ipython-input-5-0563709f3c08>:24: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
ax = fig.add_subplot()
The resulting pdf file does not contain a single page with multiple graphs (which is what I want like in the first image) but just a single page with a single graph:
What exactly am I doing wrong? I greatly appreciate any feedback you can give.
Here is a solution that should meet your needs. It reads the csv file into a dataframe and iterates through the columns of the dataframe to plot corresponding subplots.
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
def graph_file(f: str):
df = pd.read_csv(f)
fig, axs = plt.subplots(nrows=3, ncols=3)
fig.set_size_inches(20, 10)
fig.subplots_adjust(wspace=0.5)
fig.subplots_adjust(hspace=0.5)
fname = f[:-4] + '.pdf'
with PdfPages(fname) as pdf:
for col, ax in zip(df.columns[1:], axs.flatten()):
ax.plot(df['time (days)'], df[col])
ax.set(xlabel='time (days)', ylabel=col)
ax.tick_params(axis='x', labelrotation=30)
pdf.savefig(bbox_inches='tight')
plt.show()

How to save multiple figure objects without knowing their variable names beforehand [duplicate]

I would like to:
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
# ...
for i, figure in enumerate(pylab.MagicFunctionReturnsListOfAllFigures()):
figure.savefig('figure%d.png' % i)
What is the magic function that returns a list of current figures in pylab?
Websearch didn't help...
Pyplot has get_fignums method that returns a list of figure numbers. This should do what you want:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(100)
y = -x
plt.figure()
plt.plot(x)
plt.figure()
plt.plot(y)
for i in plt.get_fignums():
plt.figure(i)
plt.savefig('figure%d.png' % i)
The following one-liner retrieves the list of existing figures:
import matplotlib.pyplot as plt
figs = list(map(plt.figure, plt.get_fignums()))
Edit: As Matti Pastell's solution shows, there is a much better way: use plt.get_fignums().
import numpy as np
import pylab
import matplotlib._pylab_helpers
x=np.random.random((10,10))
y=np.random.random((10,10))
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
figures=[manager.canvas.figure
for manager in matplotlib._pylab_helpers.Gcf.get_all_fig_managers()]
print(figures)
# [<matplotlib.figure.Figure object at 0xb788ac6c>, <matplotlib.figure.Figure object at 0xa143d0c>]
for i, figure in enumerate(figures):
figure.savefig('figure%d.png' % i)
This should help you (from the pylab.figure doc):
call signature::
figure(num=None, figsize=(8, 6),
dpi=80, facecolor='w', edgecolor='k')
Create a new figure and return a
:class:matplotlib.figure.Figure
instance. If num = None, the
figure number will be incremented and
a new figure will be created.** The
returned figure objects have a
number attribute holding this number.
If you want to recall your figures in a loop then a good aproach would be to store your figure instances in a list and to call them in the loop.
>> f = pylab.figure()
>> mylist.append(f)
etc...
>> for fig in mylist:
>> fig.savefig()
Assuming you haven't manually specified num in any of your figure constructors (so all of your figure numbers are consecutive) and all of the figures that you would like to save actually have things plotted on them...
import matplotlib.pyplot as plt
plot_some_stuff()
# find all figures
figures = []
for i in range(maximum_number_of_possible_figures):
fig = plt.figure(i)
if fig.axes:
figures.append(fig)
else:
break
Has the side effect of creating a new blank figure, but better if you don't want to rely on an unsupported interface
I tend to name my figures using strings rather than using the default (and non-descriptive) integer. Here is a way to retrieve that name and save your figures with a descriptive filename:
import matplotlib.pyplot as plt
figures = []
figures.append(plt.figure(num='map'))
# Make a bunch of figures ...
assert figures[0].get_label() == 'map'
for figure in figures:
figure.savefig('{0}.png'.format(figure.get_label()))

How can I plot specific attributes rather than default of all attributes in Time Series

How can I plot specific attributes of a time series and not the default of all attributes in the Data Frame. I would like to make a Time Series of a particular attribute and two particular attributes. Is it possible to make a time series graph of headcount and another time series graph of headcount and tables open? Below is the code I have been using, if I try and call specific variables I get error codes. Thanks in advance
# Load necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Load data
filename = 'https://library.startlearninglabs.uw.edu/DATASCI410/Datasets/JitteredHeadCount.csv'
headcount_df = pd.read_csv(filename)
headcount_df.describe()
headcount_df.columns
ax = plt.figure(figsize=(12, 3)).gca() # define axis
headcount_df.plot(ax = ax)
ax.set_xlabel('Date')
ax.set_ylabel('Number of guests')
ax.set_title('Time series of Casino data')
You might have to mess around with the ticks and some other formatting, but this should get you headed in the right direction.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
filename = 'https://library.startlearninglabs.uw.edu/DATASCI410/Datasets/JitteredHeadCount.csv'
headcount_df = pd.read_csv(filename)
headcount_df['DateFormat'] = pd.to_datetime(headcount_df['DateFormat'].fillna('ffill'))
headcount_df.set_index('DateFormat', inplace=True)
headcount_df.sort_index(inplace=True)
headcount_df_to = headcount_df[['TablesOpen']]
headcount_df_hc_to = headcount_df[['HeadCount', 'TablesOpen']]
fig, axes = plt.subplots(nrows=2, ncols=1,
figsize=(12, 8))
headcount_df_to.plot(ax=axes[0], color=['orange'])
headcount_df_hc_to.plot(ax=axes[1], color=['blue', 'orange'])
axes[0].set_xlabel('Date')
axes[0].set_ylabel('Tables Open')
axes[0].legend(loc='center left', bbox_to_anchor=(1, 0.5))
axes[1].set_xlabel('Date')
axes[1].set_ylabel('Number of guests and Tables Open')
axes[1].legend(loc='center left', bbox_to_anchor=(1, 0.5))
fig.suptitle('Time Series of Casino data')

Not getting the proper graph comparison using Python

I am trying to compare and get a proper point of intersection between the two CSV files. I am using the graph depiction for better understanding.
But I am getting very diminished image of one graph as compared to another.
See the following:
Here is the data: trade-volume.csv
Here is the real graph:
Here is the data: miners-revenue.csv
Here is the real graph:
Here is the program I wrote for comparison:
import pandas as pd
import matplotlib.pyplot as plt
dat2 = pd.read_csv("trade-volume.csv", parse_dates=['time'])
dat3 = pd.read_csv("miners-revenue.csv", parse_dates=['time'])
dat2['timeDiff'] = (dat2['time'] - dat2['time'][0]).astype('timedelta64[D]')
dat3['timeDiff'] = (dat3['time'] - dat3['time'][0]).astype('timedelta64[D]')
fig, ax = plt.subplots()
ax.plot(dat2['timeDiff'], dat2['Value'])
ax.plot(dat3['timeDiff'], dat3['Value'])
plt.show()
I got the output like the following:
As one can see the orange color graph is very low and I could not understand the points as it is lower. I am willing to overlap the graphs and then check.
Please help me make it possible with my existing code, if no alteration required.
The problem comes down to your y axis. One has a maximum of 60,000,000 while the other has a maximum of 6,000,000,000. Trying to plot these on the same graph is going to lead to one "looking" like a straight line even though it isn't if you zoom in.
A possible solution is to use a second y axis (you can change the color of the lines using the color= argument in ax.plot():
import pandas as pd
import matplotlib.pyplot as plt
dat2 = pd.read_csv("trade-volume.csv", parse_dates=['time'])
dat3 = pd.read_csv("miners-revenue.csv", parse_dates=['time'])
dat2['timeDiff'] = (dat2['time'] - dat2['time'][0]).astype('timedelta64[D]')
dat3['timeDiff'] = (dat3['time'] - dat3['time'][0]).astype('timedelta64[D]')
fig, ax = plt.subplots()
ax.plot(dat2['timeDiff'], dat2['Value'], color="blue")
ax2=ax.twinx()
ax2.plot(dat3['timeDiff'], dat3['Value'], color="red")
plt.show()
Both data live on very different scales. You may normalize both in order to compare them.
import pandas as pd
import matplotlib.pyplot as plt
dat2 = pd.read_csv("trade-volume.csv", parse_dates=['time'])
dat3 = pd.read_csv("miners-revenue.csv", parse_dates=['time'])
dat2['timeDiff'] = (dat2['time'] - dat2['time'][0]).astype('timedelta64[D]')
dat3['timeDiff'] = (dat3['time'] - dat3['time'][0]).astype('timedelta64[D]')
fig, ax = plt.subplots()
ax.plot(dat2['timeDiff'], dat2['Value']/dat2['Value'].values.max())
ax.plot(dat3['timeDiff'], dat3['Value']/dat3['Value'].values.max())
plt.show()

Python Matplotlib add Colorbar

i've got a problem using MatlobLib with "Custom" Shapes from a shapereader. Importing and viewing inserted faces works fine, but i'm not able to place a colorbar on my figure.
I already tried several ways from the tutorial, but im quite sure there is a smart solution for this problem.
maybe somebody can help me, my current code is attached below:
from formencode.national import pycountry
import itertools
from matplotlib import cm, pyplot
from matplotlib import
from mpl_toolkits.basemap import Basemap
from numpy.dual import norm
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import matplotlib as mpl
import matplotlib.colors as colors
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import numpy as np
def draw_map_for_non_normalized_data_with_alpha2_counrty_description(data, title=None):
m = Basemap()
ax = plt.axes(projection=ccrs.PlateCarree())
list = []
sum = 0
for key in data:
sum += data[key]
for key in data.keys():
new_val = (data[key]+0.00)/sum
list.append(new_val)
data[key] = new_val
#===========================================================================
# print str(min(list))
# print str(max(list))
#===========================================================================
cmap = mpl.cm.cool
colors = matplotlib.colors.Normalize(min(list)+0.0, max(list)+0.0)
labels = []
features = []
for country in shpreader.Reader(shapename).records():
a3_code = country.attributes["gu_a3"]
try :
a2_code = pycountry.countries.get(alpha3=a3_code).alpha2
except:
a2_code = ""
if a2_code in data:
val = data[a2_code]
color = cm.jet(norm(val))
print str(val) + " value for color: " + str(color)
labels.append(country.attributes['name_long'])
feat = ax.add_geometries(country.geometry, ccrs.PlateCarree(), facecolor=color, label=country.attributes['name_long'])
features.append(feat)
#ax.legend(features, labels, loc='upper right')
#===========================================================================
# fig = pyplot.figure(figsize=(8,3))
# ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
#===========================================================================
#cbar = m.colorbar(location='bottom')
cb1 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,norm=colors,orientation='horizontal')
cb1.set_label('foo')
m.drawcoastlines()
m.drawcountries()
if title:
plt.title(title)
plt.show()
as you can see inside the code, i already tried several ways, but none of them worked for me.
maybe somebody has "the" hint for me.
thanks for help,
kind regards
As mentioned in the comments above, i would think twice about mixing Basemap and Cartopy, is there a specific reason to do so? Both are basically doing the same thing, extending Matplotlib with geographical plotting capabilities. Both are valid to use, they both have their pro's and con's.
In your example you have a Basemap axes m, a Cartopy axes ax and you are using the Pylab interface by using plt. which operates on the currently active axes. Perhaps it theoretically possible, but it seems prone to errors to me.
I cant modify your example to make it work, since the data is missing and your code is not valid Python, the indentation for the function is incorrect for example. But here is a Cartopy-only example showing how you can plot a Shapefile and use the same cmap/norm combination to add a colorbar to the axes.
One difference with your code is that you provide the axes containing the map to the ColorbarBase function, this should be a seperate axes specifically for the colorbar.
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib as mpl
import cartopy.io.shapereader as shpreader
fig, ax = plt.subplots(figsize=(12,6),
subplot_kw={'projection': ccrs.PlateCarree()})
norm = mpl.colors.Normalize(vmin=0, vmax=1000000)
cmap = plt.cm.RdYlBu_r
for n, country in enumerate(shpreader.Reader(r'D:\ne_50m_admin_0_countries_lakes.shp').records()):
ax.add_geometries(country.geometry, ccrs.PlateCarree(),
facecolor=cmap(norm(country.attributes['gdp_md_est'])),
label=country.attributes['name'])
ax.set_title('gdp_md_est')
cax = fig.add_axes([0.95, 0.2, 0.02, 0.6])
cb = mpl.colorbar.ColorbarBase(cax, cmap=cmap, norm=norm, spacing='proportional')
cb.set_label('gdp_md_est')

Categories