I am making a pie chart that looks like this.
I want to make multiple pie charts for different sets of data and keep the colours fixed to the legend names, but when the order changes, the colour scheme follows the order.
Is there a way to pass a dict into the chart to fix the colours to specific items?
[]
You cannot pass a dictionary with your colors, but you can specify the colors manually, set sort to False and pass the values always in the same order, e.g.
import plotly
fig = {
'data': [{'labels': ['Residential', 'Non-Residential', 'Utility'],
'values': [19, 26, 55],
'type': 'pie',
'sort': False,
'marker': {'colors': ['rgb(255, 0, 0)',
'rgb(0, 255, 0)',
'rgb(0, 0, 255)']
}
}]
}
fig = {
'data': [{'labels': ['Residential', 'Non-Residential', 'Utility'],
'values': [100, 10, 25],
'type': 'pie',
'sort': False,
'marker': {'colors': ['rgb(255, 0, 0)',
'rgb(0, 255, 0)',
'rgb(0, 0, 255)']
}
}]
}
plotly.offline.plot(fig)
Related
I have a Figure made up of 4 subplots, each subplot looks like this:
Data:Histogram({
'autobinx': False,
'histnorm': 'probability density',
'legendgroup': 'HOM_TP',
'marker': {'color': '#eb8909'},
'name': 'HOM_TP',
'opacity': 0.7,
'x': array([99., 99., 99., ..., 99., 99., 99.]),
'xaxis': 'x',
'xbins': {'end': 99.0, 'size': 0.0, 'start': 99.0},
'yaxis': 'y'
})
Layout({
'annotations': [{'showarrow': False,
'text': 'TEXT',
'x': 2.5,
'xanchor': 'left',
'xref': 'x',
'y': 1,
'yanchor': 'top',
'yref': 'y domain'}],
'shapes': [{'line': {'color': 'green', 'dash': 'dash', 'width': 3},
'type': 'line',
'x0': 2.5,
'x1': 2.5,
'xref': 'x',
'y0': 0,
'y1': 1,
'yref': 'y domain'}],
'sliders': [{'active': 10,
'currentvalue': {'prefix': 'Frequency: '},
'pad': {'t': 50},
'steps': [{'args': [{'visible': [True]}, {'title': 'Slider switched to step: 0'}], 'method': 'update'}]}],
'template': '...'
})
I can add each plot to the main Figure using add_trace(subplot.data) but this does not bring the layout info (sliders and vertical line). How can I add the layout to the subplots within the main figure?
Current code:
def make_tiled_figure(subfigs, metric):
'''
Take list of figures ( figure factory plot objects) to be combined into
tiled image. Return single figure object with tiled subplots.
'''
fig = make_subplots(rows=1, cols=4, subplot_titles=[
'SNP', 'INDEL', 'HET', 'HOM'])
# decide on position and add subfigures to plot
for i, subfig in enumerate(subfigs):
if subfig:
for trace in subfig.data:
fig.add_trace(trace, row=1, col=i+1)
fig.update_layout(subfig.layout)
# specify plot size and title
fig.update_layout(height=500, width=1800, title_text=metric)
return fig
My eventual goal is to have a vertical line that can slide across each subplot, controlled by the sliders (essentially by having multiple lines made visible/invisible by the slider position). If there is a better way of achieving this I am very open to suggestions.
I'm developing in Python using the pandas, numpy and matplotlib modules, to paint various subplots of a dataframe, using the following code:
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.ticker as ticker
data = {'Name': ['Status', 'Status', 'HMI', 'Allst', 'Drvr', 'CurrTUBand', 'RUSource', 'RUReqstrPriority', 'RUReqstrSystem', 'RUResReqstStat', 'CurrTUBand', 'DSP', 'SetDSP', 'SetDSP', 'DSP', 'RUSource', 'RUReqstrPriority', 'RUReqstrSystem', 'RUResReqstStat', 'Status', 'Delay', 'Status', 'Delay', 'HMI', 'Status', 'Status', 'HMI', 'DSP'],
'Value': [4, 4, 2, 1, 1, 1, 0, 7, 0, 4, 1, 1, 3, 0, 3, 0, 7, 0, 4, 1, 0, 1, 0, 1, 4, 4, 2, 3],
'Id_Par': [0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 0, 0, 22, 22, 28, 28, 28, 28, 0, 0, 38, 38, 0, 0, 0, 0, 0]
}
signals_df = pd.DataFrame(data)
def plot_signals(signals_df):
# Count signals by parallel
signals_df['Count'] = signals_df.groupby('Id_Par').cumcount().add(1).mask(signals_df['Id_Par'].eq(0), 0)
# Subtract Parallel values from the index column
signals_df['Sub'] = signals_df.index - signals_df['Count']
id_par_prev = signals_df['Id_Par'].unique()
id_par = np.delete(id_par_prev, 0)
signals_df['Prev'] = [1 if x in id_par else 0 for x in signals_df['Id_Par']]
signals_df['Final'] = signals_df['Prev'] + signals_df['Sub']
# Convert and set Subtract to index
signals_df.set_index('Final', inplace=True)
# Get individual names and variables for the chart
names_list = [name for name in signals_df['Name'].unique()]
num_names_list = len(names_list)
# Creation Graphics
fig, ax = plt.subplots(nrows=num_names_list, figsize=(10, 10), sharex=True)
plt.xticks(color='SteelBlue', fontweight='bold')
# Matplotlib's categorical feature to convert x-axis values to string
x_values = [-1, ]
for name in all_names_list:
x_values.append(signals_df[signals_df["Name"] == name]["Value"].index.values[0])
x_values.append(len(signals_df) - 1)
x_values = [str(i) for i in sorted(set(x_values))]
print(x_values)
for pos, (a_, name) in enumerate(zip(ax, names_list)):
# Creating a dummy plot and then remove it
dummy, = ax[pos].plot(x_values, np.zeros_like(x_values))
dummy.remove()
# Get data
data = signals_df[signals_df["Name"] == name]["Value"]
# Get values axis-x and axis-y
x_ = np.hstack([-1, data.index.values, len(signals_df) - 1])
y_ = np.hstack([0, data.values, data.iloc[-1]])
# Plotting the data by position
ax[pos].plot(x_.astype('str'), y_, drawstyle='steps-post', marker='*', markersize=8, color='k', linewidth=2)
ax[pos].set_ylabel(name, fontsize=8, fontweight='bold', color='SteelBlue', rotation=30, labelpad=35)
ax[pos].yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
ax[pos].yaxis.set_tick_params(labelsize=6)
ax[pos].grid(alpha=0.4, color='SteelBlue')
# Labeling the markers with CAN-Values
for i in range(len(y_)):
if i == 0:
xy = [x_[0].astype('str'), y_[0]]
else:
xy = [x_[i - 1].astype('str'), y_[i - 1]]
ax[pos].text(x=xy[0], y=xy[1], s=str(xy[1]), color='k', fontweight='bold', fontsize=12)
plt.show()
plot_signals(signals_df)
I'm having trouble when names get repeated, using Matplotlib's categorical feature and converting x-axis values to string; taking into consideration the focus of the answer; this is what is bringing me:
I have been trying to change the pandas conditions, since it is the condition that I am using in this line: x_values.append(signals_df[signals_df["Name"] == name]["Value"].index.values[0]) and when I print the variable x_values it brings me the wrong indices: ['-1', '0', '2', '3', '4', '5', '6', '11', '12', '20', '27'] and I can't make it work well.
I expect to achieve is a graph like the following:
The yellow shading is the jumps that it must make on the x-axis and that it are not painting on the y-axis. Thank you very much to anyone who can help me, any comments help.
I leave this answer for possible searches later for someone with the same topic. I found my error, the way I was handling the for loop was not correct, I replaced it and modified it as follows:
# Matplotlib's categorical feature and to convert x-axis values to string
x_values = [-1,]
x_values + = (list (set (can_signals.index)))
x_values = [str (i) for i in sorted (x_values)]
This now allows to bring up the graph as below:
I am trying to order 4 dictionary lists from lowest to highest and I am invalid syntax (I am new to bioinformatics)
I have tried inline sorting
lists = sorted(list_dct.items, key=lambda k: k['name'])
list_dct = [{'name': 0.5, 0, 0, 0.5},
{'name' : 0.25, 0.25, 0.25, 0.25},
{'name' : 0, 0, 0, 1},
{'name' : 0.25, 0, 0.5, 0.25}]
print(lists)
I am getting an invalid syntax message... I should get the lists sorted by row lowest to row highest
You need to construct your dictionaries correctly. I've chosen to make the values a list. Then sort them with a list comprehension:
list_dct = [{'name': [0.5, 0, 0, 0.5]},
{'name' : [0.25, 0.25, 0.25, 0.25]},
{'name' : [0, 0, 0, 1]},
{'name' : [0.25, 0, 0.5, 0.25]}]
sorted([ d.get('name') for d in list_dct ])
1.) Define list_dct before the sorted() function, otherwise it's syntax error
2.) You want to sort whole list_dct, not list_dct.items()
3.) Make custom key= sorting function, where from each item we're sorting we select 'name' key.
list_dct = [{'name': [0.5, 0, 0, 0.5]},
{'name' : [0.25, 0.25, 0.25, 0.25]},
{'name' : [0, 0, 0, 1]},
{'name' : [0.25, 0, 0.5, 0.25]}]
lists = sorted(list_dct, key=lambda k: k['name'])
from pprint import pprint
pprint(lists)
Prints:
[{'name': [0, 0, 0, 1]},
{'name': [0.25, 0, 0.5, 0.25]},
{'name': [0.25, 0.25, 0.25, 0.25]},
{'name': [0.5, 0, 0, 0.5]}]
I am trying to plot the line for a set of points. Currently, I have set of points as Column names X, Y and Type in the form of a data frame. Whenever the type is 1, I would like to plot the points as dashed and whenever the type is 2, I would like to plot the points as a solid line.
Currently, I am using for loop to iterate over all points and plot each point using plt.dash. However, this is slowing down my run time since I want to plot more than 40000 points.
So, is an easy way to plot the line overall points with different line dash type?
You could realize it by drawing multiple line segments like this
(Bokeh v1.1.0)
import pandas as pd
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, Range1d, LinearAxis
line_style = {1: 'solid', 2: 'dashed'}
data = {'name': [1, 1, 1, 2, 2, 2, 1, 1, 1, 1],
'counter': [1, 2, 3, 3, 4, 5, 5, 6, 7, 8],
'score': [150, 150, 150, 150, 150, 150, 150, 150, 150, 150],
'age': [20, 21, 22, 22, 23, 24, 24, 25, 26, 27]}
df = pd.DataFrame(data)
plot = figure(y_range = (100, 200))
plot.extra_y_ranges = {"Age": Range1d(19, 28)}
plot.add_layout(LinearAxis(y_range_name = "Age"), 'right')
for i, g in df.groupby([(df.name != df.name.shift()).cumsum()]):
source = ColumnDataSource(g)
plot.line(x = 'counter', y = 'score', line_dash = line_style[g.name.unique()[0]], source = source)
plot.circle(x = 'counter', y = 'age', color = "blue", size = 10, y_range_name = "Age", source = source)
show(plot)
I have a dataset with about 9800 entries. One column contains user names (about 60 individual user names). I want to generate a scatter plot in matplotlib and assign different colors to different users.
This is basically what I do:
import matplotlib.pyplot as plt
import pandas as pd
x = [5, 10, 20, 30, 5, 10, 20, 30, 5, 10, 20, 30]
y = [100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600]
users =['mark', 'mark', 'mark', 'rachel', 'rachel', 'rachel', 'jeff', 'jeff', 'jeff', 'lauren', 'lauren', 'lauren']
#this is how the dataframe basicaly looks like
df = pd.DataFrame(dict(x=x, y=y, users=users)
#I go on an append the df with colors manually
#I'll just do it the easy albeit slow way here
colors =['red', 'red', 'red', 'green', 'green', 'green', 'blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow']
#this is the dataframe I use for plotting
df1 = pd.DataFrame(dict(x=x, y=y, users=users, colors=colors)
plt.scatter(df1.x, df1.y, c=df1.colors, alpha=0.5)
plt.show()
However, I don't want to assign colors to the users manually. I have to do this many times in the coming weeks and the users are going to be different every time.
I have two questions:
(1) Is there a way to assign colors automatically to the individual users?
(2) If so, is there a way to assign a color scheme or palette?
user_colors = {}
unique_users = list(set(users))
step_size = (256**3) // len(unique_users)
for i, user in enumerate(unique_users):
user_colors[user] = '#{}'.format(hex(step_size * i)[2:])
Then you've got a dictionary (user_colors) where each user got one unique color.
colors = [user_colors[user] for user in users]
Now you've got your array with a distinct color for each user