I have an array of RGB values for individual pixels of a digital result that has analyzed an image. The array represents rows of individual pixels, which make up the image. The resulting image shows me what groups of pixels qualify as being "hot spots".
I'm using RMagick in Ruby and I'm wanting to build this result image from the arrays of pixels that I have. I'm not clear as to how I can import that array as the visual pixel colours. An example:
imagepixels = [
[[0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0]],
[[0,0,0], [0,0,0], [255,0,0], [0,0,0], [0,0,0]],
[[0,0,0], [0,0,0], [255,0,0], [255,0,0], [0,0,0]],
[[0,0,0], [255,0,0], [255,0,0], [255,0,0], [0,0,0]],
[[0,0,0], [255,0,0], [255,0,0], [255,0,0], [0,0,0]],
[[0,0,0], [255,0,0], [255,0,0], [255,0,0], [0,0,0]],
[[0,0,0], [0,0,0], [255,0,0], [255,0,0], [0,0,0]],
[[0,0,0], [0,0,0], [255,0,0], [0,0,0], [0,0,0]],
[[0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0]]
]
I can't seem to get any methods to work from RMagick, but I have found this one, which I'm confused over:
.import_pixels(blob, columns, rows, depth, map, format = 'png') ⇒ MiniMagick::Image
Is there an easier way to get these pixels into the Magick object, then write the file? Or how can I get this done, given the array that I already have?
Cheers
It looks like the constitute method will serve your needs.
Related
I'm trying to plot a seaborn countplot with parameter x and hue:
data = {"group1":[1, 2, 3, 1, 2, 3, 1, 1, 2, 2], "group2":["A", "B", "C", "A", "A", "B", "C", "B", "A", "C"]}
df = pd.DataFrame(data=data)
sns.countplot(data=df, x="group1", hue="group2")
plt.show()
Output:
I want to add another X ticks in the same graph, summerizng values acorss all other xticks (A value would be 4, B value would be 3, C value would be 3).
How can I do it?
I was trying to find an elegantly looking solution to your request, but have only come to this yet:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data = {"group1":[1, 2, 3, 1, 2, 3, 1, 1, 2, 2],
"group2":["A", "B", "C", "A", "A", "B", "C", "B", "A", "C"]}
df = pd.DataFrame(data=data)
g1 = sns.countplot(data=df, x="group1", hue="group2")
count_labels = np.repeat(df["group2"].value_counts().values, # repeat group2 category counts
3) # for number of group1 categories/x-ticks
g2 = g1.twiny() # add twin axes with shared y-axis
g2.set_xticks([p.get_x() for p in g1.patches]) # place ticks at where g1 bars are
g2.set_xticklabels(count_labels) # assign tick labels
g2.set_xlabel("group2 category count")
g2.xaxis.set_ticks_position("bottom")
g2.xaxis.set_label_position("bottom")
g2.spines["bottom"].set_position(("axes", -0.2))
g2.spines["bottom"].set_visible(False)
plt.tick_params(which="both", top=False)
This is what it looks like:
So I thought you might rather want to annotate the bars:
for p, label in zip(g1.patches, count_labels):
g1.annotate(label, (p.get_x()+0.1, 0.1))
And it looks like this:
In case you want to use subplots:
fig, axes = plt.subplots(2, 1)
g1 = sns.countplot(data=df, x="group1", hue="group2", ax=axes[0])
g2 = sns.countplot(data=df, x="group2", ax=axes[1])
This would look this way:
I have the following dataframe
df = pd.DataFrame({
'Product': ['AA', 'AA', 'BB', 'BB', 'AA', 'AA', 'BB', 'BB'],
'Sales': [ 200, 100, 400, 100, 300, 100, 200, 500],
'Price': [ 5, 3, 3, 6, 4, 7, 4, 1]})
I would like to plot the regression line of the overall data, but also the scatter points by hue (in this case by Product) in the same chart.
I can get the regression line by:
g = sns.jointplot(y='Sales', x='Price', data=df, kind='reg', scatter = False)
And I can get the scatter by:
g = sns.scatterplot(y='Sales', x='Price', data=df, hue='Product')
But there are two different charts. Anyway that I can combine the two commands?
You have to tell the scatterplot in which axis object you want to plot. Options for a seaborn jointplot are the main plot area ax_joint or the two minor plot areas ax_marg_x and ax_marg_y.
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
df = pd.DataFrame({
'Product': ['AA', 'AA', 'BB', 'BB', 'AA', 'AA', 'BB', 'BB'],
'Sales': [ 200, 100, 400, 100, 300, 100, 200, 500],
'Price': [ 5, 3, 3, 6, 4, 7, 4, 1]})
g = sns.jointplot(y='Sales', x='Price', data=df, kind='reg', scatter = False)
sns.scatterplot(y='Sales', x='Price', data=df, hue="Product", ax=g.ax_joint)
plt.show()
Sample output:
To extend on Mr. T's answer, you could also do something like this to keep the kde marginal plots of the jointplot:
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
df = pd.DataFrame({
'Product': ['AA', 'AA', 'BB', 'BB', 'AA', 'AA', 'BB', 'BB'],
'Sales': [ 200, 100, 400, 100, 300, 100, 200, 500],
'Price': [ 5, 3, 3, 6, 4, 7, 4, 1]})
g = sns.jointplot(y='Sales', x='Price', data=df, hue="Product", alpha=0.5, xlim=(0.5,7.5), ylim=(-50, 550))
g1 = sns.regplot(y='Sales', x='Price', data=df, scatter=False, ax=g.ax_joint)
regline = g1.get_lines()[0]
regline.set_color('red')
regline.set_zorder(5)
plt.show()
Let's say now I have an array that used to describe the shape of a polygon:
[
[0.0, 1.0],
[0.5, 1.0],
[0.5, 0.3],
[1.0, 0.3],
[1.0, 0.0],
[0.0, 0.0]
]
As shown on diagram above, the blue line(s) or vector points list is the result I was looking for.
Assuming the polygon only composed of one or more rectangular shapes, is there any way to extract/simplify the polygon to one or more lines?
Following this question,
D3.geo : Spherical arcs rather than straight lines for parallels?
I was able to draw projected polygons (1) by using path:
var poligono = {
"type": "Polygon",
"coordinates": [
[[0, 0], [0, 20], [100, 20], [100, 0], [0, 0]]
]
}
// [...]
svg.append("path")
.attr("class", "arc")
.attr("d", path(poligono));
and unprojected rectangles (2) using .outline():
var arc = d3.geoGraticule()
.extentMajor([[0, 0], [-20, -20]])
// [...]
svg.append("path")
.attr("class", "arc")
.attr("d", path(arc.outline()));
What is the best way to draw a polygon such as the blue one in the figure (3), i.e. an unprojected polygon enrolling the cylinder for more than 360°?
(The general goal is to draw this kind of surfaces on a generic cylinder, and not specifically on a geographic projection)
I have a Graphics3D object. I want to export it as a bitmap, and to calculate the bitmap-pixel coordinates of certain 3D points.
Mathematica obviously does a projection from 3D objects to 2D pixel coordinates when it draws the 3D graphic. How can I find out what this projection is?
I'd rather avoid doing lots of tricky geometrical calculations based on ViewVector and ViewAngle and ImageSize and BoundingBox. Is there a shortcut?
Damon.
You could GeometricTransform using the option "Transformation" -> "Perspective". Suppose your projected chess board looks something like this
img = Image#
Plot3D[0, {x, -1, 1}, {y, -1, 1}, Mesh -> 7,
MeshShading -> {{Black, White}, {White, Black}}, Boxed -> False,
AxesEdge -> {{-1, -1}, {-1, -1}, None}, AxesOrigin -> {-1, -1, 0}]
To find the projection you will need the coordinates of at least 4 control points in img for which you know the {x,y}-coordinates. There probably are methods to have Mathematica find these coordinates automatically but you can select them manually by right-clicking on img and choosing "Get Coordinates". Click on the control points of your choice (in this case I chose the 4 corners of the chessboard) and
copy/paste their coordinates to a new line. You should get something like
controls = {{13.5`, 151.5`}, {235.5`, 68.5`},
{332.5`, 206.5`}, {139.5`, 262.5`}};
The projection function and matrix then become
transform = FindGeometricTransform[controls,
{{0, 0}, {8, 0}, {8, 8}, {0, 8}},
"Transformation" -> "Perspective"][[2]]
transfMat = TranformationMatrix[transform]
Note that I chose the chessboard to be an 8x8 square centred at {4,4}, but you can choose any square.
A point {x,y} on the chessboard will now correspond to the point in img with pixel coordinates transform[{x,y}] or, using the projection matrix, (transfMat[[{1,2}]].{x,y,1})/(transfMat[[3]].{x,y,1}). So for example, to put a marker on D6, which would be at position {x,y}={4-1/2,6-1/2} in my 8x8 square, you could do something like
ImageCompose[img, Image[BoxMatrix[2]], Round[transform[{4 - 1/2, 6 - 1/2}]]]
When you render your Graphics3D object, you can specify the ViewMatrix option. You can set the transformation (such as a rotation) and then the projection.
This way you can use your explicit knowledge of the projection used to calculate the correct planar coordinates.