global change to the universal default color of plotly #444 - colors

Currently, the default color of traces, borders, ticks, outlines, etc, as noted here, is #444. Has anyone found a way to change this default setting instead of specifying each and every single feature one would like to change?

You can start defining your template you want. Then you should add template=template to all plots you want to apply these settings:
import plotly.express as px
import plotly.graph_objs as go
# Create the template
# Put this block in the top of your file
template = go.layout.Template(
layout=go.Layout(
paper_bgcolor="#333333",
plot_bgcolor="#333333"
)
)
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16], template=template)
fig.show()

Related

Matplotlib not displaying all values

I am trying to display the following values in the form of a bar chart. However, I am only getting one value displayed (619,1). Below is the code which I used in an attempt to plot the below graph:
import matplotlib.pyplot as plt
plt.style.use('ggplot')
values= [1, 2, 3, 4, 5]
a = [619, 101, 815, 1361, 178]
plt.figure(figsize=(5, 5))
plt.bar(a, values)
plt.show()
The bar width is set to a default value of 0.8 so when your x-axis has such a large range, the bars are so skinny that they disappear.
The reason for the 0.8 is that bar charts are typically used for labelled categories, which are effectively spaced by 1 along the x-axis.
So you can set the width directly. (It's also possible to calculate a width, to make this more automatic, but then you need to decide about overlaps, etc.)
plt.figure(figsize=(5, 5))
plt.xlim(0, 1450)
plt.bar(a, values, width = 50)
It seems your data might be better suited for a horizontal bar plot (but don't take this too seriously as it may not have the right meaning at all), and if you want horizontal bars, you can do so like this:
plt.barh(values, a)

How do I reliably specify the font of text in matplotlib?

I've been trying to specify the font for my plots through:
plt.rcParams['font.family'] = ...
plt.rcParams["mathtext.fontset"] = ...
and I've had a lot of headaches because of it. I get the error:
"C:\Users\chris\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\font_manager.py:1241: UserWarning: findfont: Font family ... not found. Falling back to DejaVu Sans."
My goal is the title: Some/Any way really, to specify fonts reliably in mpl. I don't care how many hoops I have to jump through at this point, I just want something to work.
From what I understand, matplotlib.font_manager() finds all the available fonts on my system (no matter where they come from) and provides me with the full path to them. What I tried to do is to generate a sample plot of each font I get from matplotlib.font_manager() and see if I get DejaVuSans of my desired font.
It works for about 12 fonts out of approx. 240. At first I thought that maybe I have the same problem as here:
matplotlib does not detect font
but I shouldn't have the scoring problem, since I'm getting the fontname from font_manager, right?
There was also a solution on github.com, but I didn't really understand what I was supposed to do with it:
https://github.com/matplotlib/matplotlib/issues/13139
Here's my sample code:
import matplotlib.font_manager
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import _rebuild; _rebuild()
import re
font_paths = matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
fonts = [re.search(r'(?<=Fonts\\)\w+', f_path).group() for f_path in font_paths]
for font in fonts:
df = pd.DataFrame({'perc': pd.Series([45, 35, 10, 5, 3, 2], index=['A', 'B', 'C','D','E','F'])})
plt.rcParams['font.family'] = font
fig, ax = plt.subplots(figsize=(7,4))
df.iloc[::-1].plot(kind='barh', legend = False, ax=ax)
ax.set_xlabel('Percentage',fontsize=15)
ax.set_ylabel('Type',fontsize=15)
plt.savefig(font+'.png')
Thanks in advance

Making a histogram/barchart

i have a Pandas dataframe, which contains 6000 values ranging between 1 and 2500, i would like to create a chart that shows a predetermined x-axis, i.e. [1,2,4,8,16,32,64,128,256,512,more] and the a bar for each of these counts, i've been looking into the numpy.histogram, bit that does not let me choose the bin range (it estimates one) same goes for matplotlib.
The codes i've tried so far is,
plt.hist(df['cnt'],bins=[0,1,2,4,8,16,32,64,128,256,512])
plt.show()
np.histogram(df['cnt'])
And the plotting the np data, but i does not look like i want it.
I hope my question makes sense, else i will try to expand.
EDIT
when i run the
plt.hist(df['cnt'],bins=[0,1,2,4,8,16,32,64,128,256,512])
plt.show()
i get:
What i want:
Where the second one have been made in Excel using the data analysis histogram function. I hope this gives a better picture of what i would like to do.
I think you want a base-2 logarithmic scale on the xaxis.
You can do that by setting ax.set_xscale('log', basex=2)
You also then need to adjust the tick locations and formatting, which you can do with ax.xaxis.set_major_locator(ticker.FixedLocator(bins)) and ax.xaxis.set_major_formatter(ticker.ScalarFormatter()
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
fig, ax = plt.subplots(1)
# Some fake data
cnt = np.random.lognormal(0.5, 2.0, 6000)
# Define your bins
bins = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
# Plot the histogram
ax.hist(cnt, bins=bins)
# Set scale to base2 log
ax.set_xscale('log', basex=2)
# Set ticks and ticklabels using ticker
ax.xaxis.set_major_locator(ticker.FixedLocator(bins))
ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
plt.show()

Second y-axis and overlapping labeling?

I am using python for a simple time-series analysis of calory intake. I am plotting the time series and the rolling mean/std over time. It looks like this:
Here is how I do it:
## packages & libraries
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
from pandas import Series, DataFrame, Panel
## import data and set time series structure
data = pd.read_csv('time_series_calories.csv', parse_dates={'dates': ['year','month','day']}, index_col=0)
## check ts for stationarity
from statsmodels.tsa.stattools import adfuller
def test_stationarity(timeseries):
#Determing rolling statistics
rolmean = pd.rolling_mean(timeseries, window=14)
rolstd = pd.rolling_std(timeseries, window=14)
#Plot rolling statistics:
orig = plt.plot(timeseries, color='blue',label='Original')
mean = plt.plot(rolmean, color='red', label='Rolling Mean')
std = plt.plot(rolstd, color='black', label = 'Rolling Std')
plt.legend(loc='best')
plt.title('Rolling Mean & Standard Deviation')
plt.show()
The plot doesn't look good - since the rolling std distorts the scale of variation and the x-axis labelling is screwed up. I have two question: (1) How can I plot the rolling std on a secony y-axis? (2) How can I fix the x-axis overlapping labeling?
EDIT
With your help I managed to get the following:
But do I get the legend sorted out?
1) Making a second (twin) axis can be done with ax2 = ax1.twinx(), see here for an example. Is this what you needed?
2) I believe there are several old answers to this question, i.e. here, here and here. According to the links provided, the easiest way is probably to use either plt.xticks(rotation=70) or plt.setp( ax.xaxis.get_majorticklabels(), rotation=70 ) or fig.autofmt_xdate().
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
plt.xticks(rotation=70) # Either this
ax.set_xticks([1, 2, 3, 4, 5])
ax.set_xticklabels(['aaaaaaaaaaaaaaaa','bbbbbbbbbbbbbbbbbb','cccccccccccccccccc','ddddddddddddddddddd','eeeeeeeeeeeeeeeeee'])
# fig.autofmt_xdate() # or this
# plt.setp( ax.xaxis.get_majorticklabels(), rotation=70 ) # or this works
fig.tight_layout()
plt.show()
Answer to Edit
When sharing lines between different axes into one legend is to create some fake-plots into the axis you want to have the legend as:
ax1.plot(something, 'r--') # one plot into ax1
ax2.plot(something else, 'gx') # another into ax2
# create two empty plots into ax1
ax1.plot([][], 'r--', label='Line 1 from ax1') # empty fake-plot with same lines/markers as first line you want to put in legend
ax1.plot([][], 'gx', label='Line 2 from ax2') # empty fake-plot as line 2
ax1.legend()
In my silly example it is probably better to label the original plot in ax1, but I hope you get the idea. The important thing is to create the "legend-plots" with the same line and marker settings as the original plots. Note that the fake-plots will not be plotted since there is no data to plot.

Can't change line's color in matplotlib with rcParams

I need a red line, but the following code part doesn't work:
import matplotlib
matplotlib.rc("lines", marker="x", linewidth=5, color="r")
import pylab
pylab.plot([1,2,3])
pylab.show()
marker and linewidth changed, but not color.
Used environment:
Operation system: Windows
IDE: PyCharm.
Python version: Python3.5 with Anaconda3
That's not really how matplotlib.rc should be used. It's more global configuration. I also don't think color alone is a valid parameter.
For just a single plot, do this:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6], linestyle='-', color='r', linewidth=2)
fig.savefig('plot_with_red_line.png', dpi=100)
Also, don't use the pylab interface. Use pyplot.
By default, colors are specified by a Cycler object. Manually specifying a color in the pyplot.plot() (or axes.Axes.plot()) command (see Paul's answer) will change the color for a single plot. If you want to change the default color for all line plots, read on.
I'll start with an example derived from the matplotlib documentation:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
plt.ion() # Interactive mode on.
data = np.random.randn(50)
# Want to change default line color to cyan.
mpl.rc('lines', linewidth=4, color='c')
# Plot; linewidth changes, color doesn't.
plt.plot(data)
The color didn't change to cyan as desired.
Now, I noticed the following line at the bottom of the page in the sample matplotlibrc file:
#lines.color : C0 ## has no affect on plot(); see axes.prop_cycle
It turns out that in order to cycle through colors in default matplotlib plots, a Cycler is assigned to axes.Axes objects. We need to provide a different cycler with the color property we want. Continuing from the previous example...
plt.close()
from cycler import cycler
custom_cycler = (cycler(color=['c', 'm', 'y', 'k']) + cycler(linewidth=[1, 2, 3, 4]))
mpl.rc('axes', prop_cycle=custom_cycler)
for i in range(5):
plt.plot(data + i)
Woohoo! We changed the default color cycle as desired and learned about Cyclers in the process, which can cycle through other properties like linewidth too. Of course, if you want all plots to be of one color, just provide a list containing a single value to the Cycler.
NOTE: It's also possible to change the property cycler for an axes.Axes instance via axes.Axes.set_prop_cycle().
NOTE 2: As Paul said, don't use pylab; use pyplot. pylab is deprecated.

Resources