Drawing a community in networkx, anything I am doing incorrectly? - matplotlib

Trying to do something like this but I am not sure what I am doing incorrectly
import networkx as nx
import matplotlib.pyplot as plt
import networkx.algorithms.community as nxcom
G = nx.karate_club_graph()
greedy = nxcom.greedy_modularity_communities(G)
#returns a list with type frozen sets within the list
#[{set1},{set2},{set3}]
pos = nx.spring_layout(G) # compute graph layout
plt.axis('off')
nx.draw_networkx_nodes(G, pos, cmap=plt.cm.RdYlBu, node_color=list(greedy.values()))
plt.show(G)

It looks like your issue comes from the way you are mapping colors to your communities. Since the node_color argument from nx.draw_networkx_nodes is expected to be a list of color (see doc here), you will need to associate each one of your nodes with the color of its community. You can do that by using:
c=plt.cm.RdYlBu(np.linspace(0,1,len(greedy))) #create a list of colors, one for each community
colors={list(g)[j]:c[i] for i,g in enumerate(greedy) for j in range(len(list(g)))} #associate each node with the color of its community
colors_sort=dict(sorted(colors.items())) #sort the dictionary by keys such
You can then convert the values of your sorted dictionnary into a list and pass it to the nx.draw_networkx_nodes with nx.draw_networkx_nodes(G, pos,node_color=list(colors_sort.values())).
See full code below:
import networkx as nx
import matplotlib.pyplot as plt
import networkx.algorithms.community as nxcom
import numpy as np
G = nx.karate_club_graph()
greedy = nxcom.greedy_modularity_communities(G)
c=plt.cm.RdYlBu(np.linspace(0,1,len(greedy)))
colors={list(g)[j]:c[i] for i,g in enumerate(greedy) for j in range(len(list(g)))}
colors_sort=dict(sorted(colors.items()))
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos,node_color=list(colors_sort.values()))
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos,labels={n:str(n) for n in G.nodes()})
plt.axis('off')
plt.show(G)

Related

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

Plotly chart percentage with smileys

I would like o add a plot figure based on smileys like this one:
dat will come from a dataframe pandas : dataframe.value_counts(normalize=True)
Can some one give me some clues.
use colorscale in normal way for a heatmap
use anotation_text to assign an emoji to a value
import plotly.figure_factory as ff
import plotly.graph_objects as go
import pandas as pd
import numpy as np
df = pd.DataFrame([[j*10+i for i in range(10)] for j in range(10)])
e=["😃","🙂","😐","☚ī¸"]
fig = go.Figure(ff.create_annotated_heatmap(
z=df.values, colorscale="rdylgn", reversescale=False,
annotation_text=np.select([df.values>75, df.values>50, df.values>25, df.values>=0], e),
))
fig.update_annotations(font_size=25)
# allows emoji to use background color
fig.update_annotations(opacity=0.7)
update coloured emoji
fundamentally you need emojicons that can accept colour styling
for this I switched to Font Awesome. This then also requires switching to dash, plotly's cousin so that external CSS can be used (to use FA)
then build a dash HTML table applying styling logic for picking emoticon and colour
from jupyter_dash import JupyterDash
import dash_html_components as html
import pandas as pd
import branca.colormap
# Load Data
df = pd.DataFrame([[j*10+i for i in range(10)] for j in range(10)])
external_stylesheets = [{
'href': 'https://use.fontawesome.com/releases/v5.8.1/css/all.css',
'rel': 'stylesheet', 'crossorigin': 'anonymous',
'integrity': 'sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf',
}]
# possibly could use a a different library for this - simple way to map a value to a colormap
cm = branca.colormap.LinearColormap(["red","yellow","green"], vmin=0, vmax=100, caption=None)
def mysmiley(v):
sm = ["far fa-grin", "far fa-smile", "far fa-meh", "far fa-frown"]
return html.Span(className=sm[3-(v//25)], style={"color":cm(v),"font-size": "2em"})
# Build App
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Table([html.Tr([html.Td(mysmiley(c)) for c in r]) for r in df.values])
])
# Run app and display result inline in the notebook
app.run_server(mode='inline')

Using Sklearn with NumPy and Images and get this error 'setting an array element with a sequence'

I am trying to create a simple image classification tool.
I would like the code below to work with classifying images. It works fine when it is a non image NumPy array.
#https://e2eml.school/images_to_numbers.html
import numpy as np
from sklearn.utils import Bunch
from PIL import Image
monkey = [1]
dog = [2]
example_animals = Bunch(data = np.array([monkey,dog]),target = np.array(['monkey','dog']))
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=2) #with KMeans you get to pre specify the number of Clusters
KModel = kmeans.fit(example_animals.data) #fit a model using the training data , in this case original example animal data passed through
import pandas as pd
crosstab = pd.crosstab(example_animals.target,KModel.labels_)
print(crosstab)
I have looked into how to make an image into a NumPy array at https://e2eml.school/images_to_numbers.html
The code below where I have converted images to NumPy array doesn't work.
When run it gets the following error
** 'setting an array element with a sequence'**
#https://e2eml.school/images_to_numbers.html
import numpy as np
from sklearn.utils import Bunch
from PIL import Image
monkey = np.asarray(Image.open("monkey.jpg"))
dog = np.asarray(Image.open("dog.jpeg"))
example_animals = Bunch(data = np.array([monkey,dog]),target = np.array(['monkey','dog']))
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=2) #with KMeans you get to pre specify the number of Clusters
KModel = kmeans.fit(example_animals.data) #fit a model using the training data , in this case original example animal data passed through
import pandas as pd
crosstab = pd.crosstab(example_animals.target,KModel.labels_)
print(crosstab)
I would appreciate any insight how I fix the error 'setting an array element with a sequence' so that the images will be compatible with the sklearn processing.
You need to be sure that your images "monkey.jpg" and "dog.jpeg" have the same number of pixels. Otherwise, you will have to resize the images to have the same size. Moreover, the data of your Bunch object need to be of shape (n_samples, n_features) (you can check the documentation https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans.fit)
You need to be aware that you use an unserpervised learning model (Kmeans). So the output of the model is not directly "monkey" or "dog".
I found the solution to error setting an array element with a sequence
Kmeans requires the data arrays for comparison need to be the same size.
This means if importing pictures, the pictures need to be resized, converted into a numpy array (a format that is compatible with Kmeans) and finally made into a 1 dimensional array.
#https://e2eml.school/images_to_numbers.html
#https://machinelearningmastery.com/how-to-load-and-manipulate-images-for-deep-learning-in-python-with-pil-pillow/
import numpy as np
from matplotlib import pyplot as plt
from sklearn.utils import Bunch
from PIL import Image
from sklearn.cluster import KMeans
import pandas as pd
monkey = Image.open("monkey.jpg")
dog = Image.open("dog.jpeg")
#resize pictures
monkey1 = monkey.resize((180,220))
dog1 = dog.resize((180,220))
#make pictures into numpy array
monkey2 = np.asarray(monkey1)
dog2 = np.asarray(dog1)
#https://www.quora.com/How-do-I-convert-image-data-from-2D-array-to-1D-using-python
#make numpy array into 1 dimensional array
monkey3 = monkey2.reshape(-1)
dog3 = dog2.reshape(-1)
example_animals = Bunch(data = np.array([monkey3,dog3]),target = np.array(['monkey','dog']))
kmeans = KMeans(n_clusters=2) #with KMeans you get to pre specify the number of Clusters
KModel = kmeans.fit(example_animals.data) #fit a model using the training data , in this case original example food data passed through
crosstab = pd.crosstab(example_animals.target,KModel.labels_)
print(crosstab)

Using perceptually uniform colormaps in Mayavi volumetric visualization

AFAIK Mayavi does not come with any perceptually uniform colormaps. I tried naively to just pass it one of Matplotlib's colormaps but it failed:
from mayavi import mlab
import multiprocessing
import matplotlib.pyplot as plt
plasma = plt.get_cmap('plasma')
...
mlab.pipeline.volume(..., colormap=plasma)
TraitError: Cannot set the undefined 'colormap' attribute of a 'VolumeFactory' object.
Edit: I found a guide to convert Matplotlib colormaps to Mayavi colormaps. However, it unfortunately doesn't work since I am trying to use a volume using a perceptually uniform colormap.
from matplotlib.cm import get_cmap
import numpy as np
from mayavi import mlab
values = np.linspace(0., 1., 256)
lut_dict = {}
lut_dict['plasma'] = get_cmap('plasma')(values.copy())
x, y, z = np.ogrid[-10:10:20j, -10:10:20j, -10:10:20j]
s = np.sin(x*y*z)/(x*y*z)
mlab.pipeline.volume(mlab.pipeline.scalar_field(s), vmin=0, vmax=0.8, colormap=lut_dict['plasma']) # still getting the same error
mlab.axes()
mlab.show()
...
Instead of setting it as the colormap argument, if you set it as the ColorTransferFunction of the volume, it works as expected.
import numpy as np
from mayavi import mlab
from tvtk.util import ctf
from matplotlib.pyplot import cm
values = np.linspace(0., 1., 256)
x, y, z = np.ogrid[-10:10:20j, -10:10:20j, -10:10:20j]
s = np.sin(x*y*z)/(x*y*z)
volume = mlab.pipeline.volume(mlab.pipeline.scalar_field(s), vmin=0, vmax=0.8)
# save the existing colormap
c = ctf.save_ctfs(volume._volume_property)
# change it with the colors of the new colormap
# in this case 'plasma'
c['rgb']=cm.get_cmap('plasma')(values.copy())
# load the color transfer function to the volume
ctf.load_ctfs(c, volume._volume_property)
# signal for update
volume.update_ctf = True
mlab.show()
While the previous answer by like444 helped me partially with a similar problem, it leads to incorrect translation between colormaps. This is because the format in which matplotlib and tvtk store color information is slightly different: Matplotlib uses RGBA, while ColorTransferFunction uses VRGB, where V is the value in the shown data that this part of the colormap is assigned to. So by doing a 1-to-1 copy, green becomes red, blue becomes green and alpha becomes blue. The following code snippet fixes that:
def cmap_to_ctf(cmap_name):
values = list(np.linspace(0, 1, 256))
cmap = cm.get_cmap(cmap_name)(values)
transfer_function = ctf.ColorTransferFunction()
for i, v in enumerate(values):
transfer_function.add_rgb_point(v, cmap[i, 0], cmap[i, 1], cmap[i, 2])
return transfer_function

Matplotlib Color Palette

Is it possible to change what colors Matplotlib cycles through when it is generating its own colors for a graph's lines? I'm using the pylab module.
from pylab import *
import matplotlib.cm as cm
x=[1,2,3,4]
y=[5,6,7,8]
fig1 = Figure()
plot1 = fig1.add_subplot(311)
plot1.plot(x,y)
plot2 = fig1.add_subplot(312)
plot2.plot(x,y)
plot3 = fig1.add_subplot(313)
plot3.plot(x,y)
Yes, of course. Since it accept many kinds of color definition. It's easy to define your own color map. Here I just get colors from the colormap hot
import pylab as py
import numpy as np
import matplotlib.cm as cm
a = np.arange(0,10)
py.figure()
for i in np.arange(10):
c = cm.hot(i/10.,1)
py.plot(a,i*a,color=c)
py.show()
The colors are extracted from color maps. You can use one of the predefined colormaps, or define your own.
Unfortunately there is no way to use multiple colormaps per figure, you have to do it manually:
import pylab as pl
import matplotlib.cm as cm
xval = pl.arange(0, 20, 0.2)
pl.subplot(311)
pl.plot(xval, pl.sin(xval), c=cm.summer(0))
pl.subplot(312)
pl.plot(xval, pl.cos(xval), c=cm.spring(0))
pl.subplot(313)
pl.plot(xval, pl.arctan(xval), xval, pl.fabs(xval))
pl.show()