Put two y-axes on an imagesc image in MATLAB - image

I have what I think is a simple problem: I have a matrix that I image using imagesc. I simply want to show a second y-axis on the right hand side of the image. How do I do that? Example:
clear all;
aMatrix = rand(20,30);
yAxis1 = 32.*(1:size(aMatrix,1));
yAxis2 = 165.*(1:size(aMatrix,1));
xAxis = 1:size(aMatrix,2);
imagesc(yAxis1, xAxis1, aMatrix);
The following will show the image with yAxis1, on the left hand side. That is great, but how do I show yAxis2 on the right hand side of the image at the same time? Thanks.

aMatrix = rand(20,30);
yAxis1 = 32.*(1:size(aMatrix,1));
yAxis2 = 165.*(1:size(aMatrix,1));
xAxis = 1:size(aMatrix,2);
h1=imagesc(xAxis, yAxis1, aMatrix);set(gca,'YDir','normal');
ax1=gca;
set(ax1,'YColor','r','YAxisLocation','right');
set(ax1,'XTickLabel',' ');
ax2=axes('Position',get(ax1,'Position'),'YAxisLocation','left');
h2=imagesc(xAxis, yAxis2,aMatrix,'Parent',ax2);
set(gca,'YDir','normal');

A quite similar solution using yyaxis :
aMatrix = rand(20,30);
yAxis1 = 32.*(1:size(aMatrix,1));
yAxis2 = 165.*(1:size(aMatrix,1));
xAxis = 1:size(aMatrix,2);
yyaxis left
imagesc(xAxis, yAxis1, aMatrix);
ax = gca;
ax.YColor = ax.XColor;
ylabel('Left Side')
yyaxis right
imagesc(xAxis, yAxis2,aMatrix);
ax.YColor = ax.XColor;
ylabel('Right Side')

Related

AmCharts 4 : Show totals of clustered and stacked charts, for individual clusters

Background:
Following the example of stacked and clustered charts as shown here I have created a chart with clustered and stacked columns. I am also attempting to display the total of the individual stacks on the top of the column as shown here
Issue faced:
The main is I am facing is the total value is displayed for all the data in the ValueAxis and not for individual stacks. Please help in displaying individual totals for the clustered columns.
Sample code:
Note the inbuilt APIs used to calculate and display totals
// Fully working example in the CodePen
// Enabling totals calculation
let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.calculateTotals = true;
// Displaying the total in the LabelBullet
let totalBullet = totalSeries.bullets.push(new am4charts.LabelBullet());
totalBullet.label.text = "{valueY.sum}";
Codepen depicting the issue (note the totals on top of the stacked columns)
Alternate approaches considered:
Adding a field in the data with the totals for the stacks and displaying it instead (Problem: Unable to deselect using the Label - the value would be static and won't change)
Other help from StackOverflow:
Found samples of showing totals on stacked charts, but unable to find help on dealing with grouping
Although this is 7months old, I didn't find an answer either for this anywhere. If you haven't found a solution yet I was able to work around this by creating two Y axes and assigning them the series individually, then adding in the 'none' series for the totals bullet as well.
I adapted your Codepen example here in jsfiddle (codepen freezes for me for some reason)
Essentially though you create the two axes, and hide the labels for the second one.
let valueAxis0 = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis0.min = 0;
valueAxis0.calculateTotals = true;
valueAxis0.title.text = "Expenditure (M)";
var valueAxis1 = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis1.renderer.grid.template.disabled = true;
valueAxis1.calculateTotals = true;
valueAxis1.syncWithAxis = chart.yAxes.getIndex(0);
valueAxis1.min = 0;
valueAxis1.renderer.labels.template.disabled = true;
Then select it when creating the series and assign to the appropriate axis with series.yAxis = valueAxis;
function createSeries(field, name, stacked, yAxes) {
var valueAxis;
if (yAxes == 0) {
valueAxis = valueAxis0;
} else if (yAxes == 1) {
valueAxis = valueAxis1;
}
let series = chart.series.push(new am4charts.ColumnSeries());
...
series.yAxis = valueAxis;
Then the same goes for the TotalSeries

Amcharts4: How to add an image to an axis (valueAxis) label?

With amcharts4, I would like to add an image to a ValueAxis's label. Is this possible? I've found out, how to add an SVG image to a bullet (see demo). But is it possible to do something similar with the label of the ValueAxis?
Here is an example of such an image, I would like to add next to the number:
Currently, the value axis looks like this and it should have an icon next to the label:
EDIT:
Thanks to #zeroin's answer, I found a solution. However, there seems to be a strange bug when using an axis bullet with a template. Not every bullet is hidden even though its label is hidden. Here's the relevant code, a screenshot and a codepen to reproduce.
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.min = 0;
valueAxis.max = 800;
valueAxis.renderer.minGridDistance = 30;
valueAxis.renderer.opposite = true;
valueAxis.renderer.labels.template.dx = 13;
valueAxis.strictMinMax = true;
var image = new am4core.Image();
image.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/man-user.svg";
image.width = 12;
image.horizontalCenter = "middle";
image.verticalCenter = "middle";
image.dx = 13;
image.dy = -0.5;
image.opacity = 0.3;
valueAxis.dataItems.template.bullet = image;
EDIT2:
This bug seems to be fixed in the current release of amcharts (4.5.14). It works now as expected.
Your question is right on time - in a version released today (4.5.9) we added bullet property to AxisDataItem. So you can add image or any other sprite to all axis labels via template or create axis range at a value you need and add bullet there, like:
var range = valueAxis.axisRanges.create();
range.value = 1500;
//range.label.text = "1500";
var image = new am4core.Image();
image.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/man-user.svg";
image.width = 15;
image.horizontalCenter = "middle";
image.verticalCenter = "middle";
image.dx = -55;
range.bullet = image;
https://codepen.io/team/amcharts/pen/JgXqvp

How to add a gap between the axes and the plot in MATLAB

I use code like this to make a plot in MATLAB 2015:
plot(rand(1,40))
box off
ax=gca;
ax.TickDir='out';
ax.TickLength=3*ax.TickLength;
]
I want to put a bit of distance between the axes and the plot like in the figure below, which I made using Photoshop:
How can I do this?
I can think of a way to do it, but:
I don't know if it's the "right" way.
It's only good for static images (i.e. if you zoom/pan the plot, the bounds won't change accordingly).
The idea is you create two more axes and specify their positions such that they're far enough from your data, then hide the original axes (either fully or partially), which gives the desired result:
%% // Create axes and plot something:
figure();
hA(1) = axes;
hA(2) = copyobj(hA(1),gcf);
hA(3) = copyobj(hA(1),gcf);
plot(hA(1),rand(1,40));
%% // Add the new axes:
%// Move them around
FRACTION_OF_POSITION = 0.6;
hA(2).Position(1) = FRACTION_OF_POSITION*hA(2).Position(1);
hA(3).Position(2) = FRACTION_OF_POSITION*hA(3).Position(2);
%// Change their style
hA(2).Color = 'none'; hA(3).Color = 'none';
hA(2).XTick = []; hA(3).YTick = [];
hA(2).XRuler.Axle.Visible = 'off';
hA(3).YRuler.Axle.Visible = 'off';
%% // Remove the box/ticks/labels of the original axes:
if true
%// Alternative 1 (Remove everything at once, including background):
set(hA(1),'Visible','off')
else
%// Alternative 2 (Remove only certain elements):
hA(1).Box = 'off';
hA(1).XRuler.Axle.Visible = 'off';
hA(1).YRuler.Axle.Visible = 'off';
end
Which results in:
Additional considerations:
If you copyobj the axes before plotting, the axis tick values would be default - you probably don't want that. You will have to set the ticks and labels manually, OR, copyobj after plotting but then delete the line child-objects of hA(2:3).
If you want to support zoom/pan behavior, this might be acheivable using linkaxes.
Credits: the idea to use .XRuler.Axle was taken from Dan here, who in turn took it from UndocumentedMatlab.

How i can convert coordinates x y from image to longitude/latitude and back?

I have image of the city, how i can get longitude/latitude for the points that i add to the image if i know 3 points like
Point1XRelative = "-18340651.0304568";
Point1YRelative = "14945227.3984772";
Point2XRelative = "-3960915.94162438";
Point2YRelative = "-7933119.6827411";
Point3XRelative = "4901426.10152285";
Point3YRelative = "13585796.8781726";
Point1XWorld = "53.1186547";
Point1YWorld = "29.2392344";
Point2XWorld = "52.6341388";
Point2YWorld = "29.7438198";
Point3XWorld = "53.0900105";
Point3YWorld = "30.0548051";
I have algrithm that can convert only for the plane and when i convert from the long/lat to x y they converts with offset.
Please advice me how i can resolve this problem.
It also depends on the zoom level. I think you will find what you need here.

Put an image in the center of a cell with migradoc

I need to put an image in the center of a table's cell.
When I add the image in a cell the image is aligned topleft.
How can I align the image in the center of a cell?
You might need to add a paragraph to the cell, set the alignment on the paragraph, and then add the image to the paragraph.
row.Cells[0].Format.Alignment = ParagraphAlignment.Center;
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row.Cells[0].AddParagraph().AddImage(imageLocation);
row.Cells[0].Format.Alignment = ParagraphAlignment.Center;
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
In my version of MigraDoc, Jeff and Reuben's solution does not work as shown: Setting the cell's Format.Alignment property has no effect, even when the image is inside a paragraph.
However, what does work for me is to put the image in a paragraph, just as Jeff and Reuben say, then give the paragraph a named style which includes centering.
In my method which predefines all my styles, I do something like:
// Here we assume the "TableText" style has already been created
var sty = doc.Styles.AddStyle( "TableTextCenter", "TableText" );
sty.ParagraphFormat.Alignment = ParagraphAlignment.Center;
And at the point where I add the image, I do this:
var para = table.Cells[ 0 ].AddParagraph();
para.Style = "TableTextCenter"; // <----- This is the magic!
var img = para.AddImage( imageFileSpec );
img.LockAspectRatio = true;
img.Width = "4cm";
img.WrapFormat = new WrapFormat {
Style = WrapStyle.Through
};
As #Reuben says, what is interesting is:
row.Cells[0].AddParagraph().AddImage(imageLocation);
I was trying with
row.Cells[0].AddImage(imageLocation);
And the image was inserted in the document but I couln't get it centered.

Resources